QuickImage – Rev 1
?pathlinks?
using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Globalization;
using System.Runtime.Serialization;
using System.Windows.Forms;
namespace CraftSynth.ImageEditor
{
/// <summary>
/// Base class for all draw objects
/// </summary>
[Serializable]
public abstract class DrawObject : IComparable, IDisposable
{
#region Members
// Object properties
private bool selected;
private Color color;
private Color fillColor;
private bool filled;
private int penWidth;
private Pen drawpen;
private Brush drawBrush;
private DrawingPens.PenType _penType;
private LineCap _endCap;
private FillBrushes.BrushType _brushType;
private string tipText;
// Last used property values (may be kept in the Registry)
private static Color lastUsedColor = Color.Black;
private static int lastUsedPenWidth = 1;
// Entry names for serialization
private const string entryColor = "Color";
private const string entryPenWidth = "PenWidth";
private const string entryPen = "DrawPen";
private const string entryBrush = "DrawBrush";
private const string entryFillColor = "FillColor";
private const string entryFilled = "Filled";
private const string entryZOrder = "ZOrder";
private const string entryRotation = "Rotation";
private const string entryTipText = "TipText";
private bool dirty;
private int _id;
private int _zOrder;
private int _rotation = 0;
private Point _center;
private bool _disposed;
#endregion Members
#region Properties
/// <summary>
/// Center of the object being drawn.
/// </summary>
public Point Center
{
get { return _center; }
set { _center = value; }
}
/// <summary>
/// Rotation of the object in degrees. Negative is Left, Positive is Right.
/// </summary>
public int Rotation
{
get { return _rotation; }
set
{
if (value > 360)
_rotation = value - 360;
else if (value < -360)
_rotation = value + 360;
else
_rotation = value;
}
}
/// <summary>
/// ZOrder is the order the objects will be drawn in - lower the ZOrder, the closer the to top the object is.
/// </summary>
public int ZOrder
{
get { return _zOrder; }
set { _zOrder = value; }
}
/// <summary>
/// Object ID used for Undo Redo functions
/// </summary>
public int ID
{
get { return _id; }
set { _id = value; }
}
/// <summary>
/// Set to true whenever the object changes
/// </summary>
public bool Dirty
{
get { return dirty; }
set { dirty = value; }
}
/// <summary>
/// Draw object filled?
/// </summary>
public bool Filled
{
get { return filled; }
set { filled = value; }
}
/// <summary>
/// Selection flag
/// </summary>
public bool Selected
{
get { return selected; }
set { selected = value; }
}
/// <summary>
/// Fill Color
/// </summary>
public Color FillColor
{
get { return fillColor; }
set { fillColor = value; }
}
/// <summary>
/// Border (line) Color
/// </summary>
public Color Color
{
get { return color; }
set { color = value; }
}
/// <summary>
/// Pen width
/// </summary>
public int PenWidth
{
get { return penWidth; }
set { penWidth = value; }
}
public FillBrushes.BrushType BrushType
{
get { return _brushType; }
set { _brushType = value; }
}
/// <summary>
/// Brush used to paint object
/// </summary>
public Brush DrawBrush
{
get { return drawBrush; }
set { drawBrush = value; }
}
public DrawingPens.PenType PenType
{
get { return _penType; }
set { _penType = value; }
}
public LineCap EndCap
{
get { return _endCap; }
set { _endCap = value; }
}
/// <summary>
/// Pen used to draw object
/// </summary>
public Pen DrawPen
{
get { return drawpen; }
set { drawpen = value; }
}
/// <summary>
/// Number of handles
/// </summary>
public virtual int HandleCount
{
get { return 0; }
}
/// <summary>
/// Number of Connection Points
/// </summary>
public virtual int ConnectionCount
{
get { return 0; }
}
/// <summary>
/// Last used color
/// </summary>
public static Color LastUsedColor
{
get { return lastUsedColor; }
set { lastUsedColor = value; }
}
/// <summary>
/// Last used pen width
/// </summary>
public static int LastUsedPenWidth
{
get { return lastUsedPenWidth; }
set { lastUsedPenWidth = value; }
}
/// <summary>
/// Text to display when mouse is over an object
/// </summary>
public string TipText
{
get { return tipText; }
set { tipText = value; }
}
#endregion Properties
#region Constructor
protected DrawObject()
{
// ReSharper disable DoNotCallOverridableMethodsInConstructor
ID = GetHashCode();
// ReSharper restore DoNotCallOverridableMethodsInConstructor
}
#endregion
#region Virtual Functions
/// <summary>
/// Clone this instance.
/// </summary>
public abstract DrawObject Clone();
/// <summary>
/// Draw object
/// </summary>
/// <param name="g">Graphics object will be drawn on</param>
public virtual void Draw(Graphics g)
{
}
#region Selection handle methods
/// <summary>
/// Get handle point by 1-based number
/// </summary>
/// <param name="handleNumber">1-based handle number to return</param>
/// <returns>Point where handle is located, if found</returns>
public virtual Point GetHandle(int handleNumber)
{
return new Point(0, 0);
}
/// <summary>
/// Get handle rectangle by 1-based number
/// </summary>
/// <param name="handleNumber"></param>
/// <returns>Rectangle structure to draw the handle</returns>
public virtual Rectangle GetHandleRectangle(int handleNumber)
{
Point point = GetHandle(handleNumber);
// Take into account width of pen
return new Rectangle(point.X - (penWidth + 3), point.Y - (penWidth + 3), 7 + penWidth, 7 + penWidth);
}
/// <summary>
/// Draw tracker for selected object
/// </summary>
/// <param name="g">Graphics to draw on</param>
public virtual void DrawTracker(Graphics g)
{
if (!Selected)
return;
SolidBrush brush = new SolidBrush(Color.Black);
for (int i = 1; i <= HandleCount; i++)
{
g.FillRectangle(brush, GetHandleRectangle(i));
}
brush.Dispose();
}
#endregion Selection handle methods
#region Connection Point methods
/// <summary>
/// Get connection point by 0-based number
/// </summary>
/// <param name="connectionNumber">0-based connection number to return</param>
/// <returns>Point where connection is located, if found</returns>
public virtual Point GetConnection(int connectionNumber)
{
return new Point(0, 0);
}
/// <summary>
/// Get connectionPoint rectangle that defines the ellipse for the requested connection
/// </summary>
/// <param name="connectionNumber">0-based connection number</param>
/// <returns>Rectangle structure to draw the connection</returns>
public virtual Rectangle GetConnectionEllipse(int connectionNumber)
{
Point p = GetConnection(connectionNumber);
// Take into account width of pen
return new Rectangle(p.X - (penWidth + 3), p.Y - (penWidth + 3), 7 + penWidth, 7 + penWidth);
}
public virtual void DrawConnection(Graphics g, int connectionNumber)
{
SolidBrush b = new SolidBrush(System.Drawing.Color.Red);
Pen p = new Pen(System.Drawing.Color.Red, -1.0f);
g.DrawEllipse(p, GetConnectionEllipse(connectionNumber));
g.FillEllipse(b, GetConnectionEllipse(connectionNumber));
p.Dispose();
b.Dispose();
}
/// <summary>
/// Draws the ellipse for the connection handles on the object
/// </summary>
/// <param name="g">Graphics to draw on</param>
public virtual void DrawConnections(Graphics g)
{
if (!Selected)
return;
SolidBrush b = new SolidBrush(System.Drawing.Color.White);
Pen p = new Pen(System.Drawing.Color.Black, -1.0f);
for (int i = 0; i < ConnectionCount; i++)
{
g.DrawEllipse(p, GetConnectionEllipse(i));
g.FillEllipse(b, GetConnectionEllipse(i));
}
p.Dispose();
b.Dispose();
}
#endregion Connection Point methods
/// <summary>
/// Hit test to determine if object is hit.
/// </summary>
/// <param name="point">Point to test</param>
/// <returns> (-1) no hit
/// (0) hit anywhere
/// (1 to n) handle number</returns>
public virtual int HitTest(Point point)
{
return -1;
}
/// <summary>
/// Test whether point is inside of the object
/// </summary>
/// <param name="point">Point to test</param>
/// <returns>true if in object, false if not</returns>
protected virtual bool PointInObject(Point point)
{
return false;
}
public abstract Rectangle GetBounds(Graphics g);
/// <summary>
/// Get cursor for the handle
/// </summary>
/// <param name="handleNumber">handle number to return cursor for</param>
/// <returns>Cursor object</returns>
public virtual Cursor GetHandleCursor(int handleNumber)
{
return Cursors.Default;
}
/// <summary>
/// Test whether object intersects with rectangle
/// </summary>
/// <param name="rectangle">Rectangle structure to test</param>
/// <returns>true if intersect, false if not</returns>
public virtual bool IntersectsWith(Rectangle rectangle)
{
return false;
}
/// <summary>
/// Move object
/// </summary>
/// <param name="deltaX">Distance along X-axis: (+)=Right, (-)=Left</param>
/// <param name="deltaY">Distance along Y axis: (+)=Down, (-)=Up</param>
public virtual void Move(int deltaX, int deltaY)
{
}
/// <summary>
/// Move handle to the point
/// </summary>
/// <param name="point">Point to Move Handle to</param>
/// <param name="handleNumber">Handle number to move</param>
public virtual void MoveHandleTo(Point point, int handleNumber)
{
}
/// <summary>
/// Dump (for debugging)
/// </summary>
public virtual void Dump()
{
Trace.WriteLine("");
Trace.WriteLine(GetType().Name);
Trace.WriteLine("Selected = " + selected.ToString(CultureInfo.InvariantCulture));
}
/// <summary>
/// Normalize object.
/// Call this function in the end of object resizing.
/// </summary>
public virtual void Normalize()
{
}
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (!this._disposed)
{
if (disposing)
{
// Free any managed objects here.
//
if (this.drawpen != null)
{
this.drawpen.Dispose();
}
if (this.drawBrush != null)
{
this.drawBrush.Dispose();
}
}
// Free any unmanaged objects here.
//
this._disposed = true;
}
}
~DrawObject()
{
this.Dispose(false);
}
#region Save / Load methods
/// <summary>
/// Save object to serialization stream
/// </summary>
/// <param name="info">The data being written to disk</param>
/// <param name="orderNumber">Index of the Layer being saved</param>
/// <param name="objectIndex">Index of the object on the Layer</param>
public virtual void SaveToStream(SerializationInfo info, int orderNumber, int objectIndex)
{
info.AddValue(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}-{2}",
entryColor, orderNumber, objectIndex),
Color.ToArgb());
info.AddValue(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}-{2}",
entryPenWidth, orderNumber, objectIndex),
PenWidth);
info.AddValue(
string.Format(CultureInfo.InvariantCulture,
"{0}{1}-{2}",
entryPen, orderNumber, objectIndex),
PenType);
info.AddValue(
string.Format(CultureInfo.InvariantCulture,
"{0}{1}-{2}",
entryBrush, orderNumber, objectIndex),
BrushType);
info.AddValue(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}-{2}",
entryFillColor, orderNumber, objectIndex),
FillColor.ToArgb());
info.AddValue(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}-{2}",
entryFilled, orderNumber, objectIndex),
Filled);
info.AddValue(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}-{2}",
entryZOrder, orderNumber, objectIndex),
ZOrder);
info.AddValue(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}-{2}",
entryRotation, orderNumber, objectIndex),
Rotation);
info.AddValue(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}-{2}",
entryTipText, orderNumber, objectIndex),
tipText);
}
/// <summary>
/// Load object from serialization stream
/// </summary>
/// <param name="info">Data from disk to parse into an object</param>
/// <param name="orderNumber">Index of the layer object resides on</param>
/// <param name="objectData">Index of the object on the layer</param>
public virtual void LoadFromStream(SerializationInfo info, int orderNumber, int objectData)
{
int n = info.GetInt32(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}-{2}",
entryColor, orderNumber, objectData));
Color = Color.FromArgb(n);
PenWidth = info.GetInt32(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}-{2}",
entryPenWidth, orderNumber, objectData));
PenType = (DrawingPens.PenType)info.GetValue(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}-{2}",
entryPen, orderNumber, objectData),
typeof(DrawingPens.PenType));
BrushType = (FillBrushes.BrushType)info.GetValue(
string.Format(CultureInfo.InvariantCulture,
"{0}{1}-{2}",
entryBrush, orderNumber, objectData),
typeof(FillBrushes.BrushType));
n = info.GetInt32(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}-{2}",
entryFillColor, orderNumber, objectData));
FillColor = Color.FromArgb(n);
Filled = info.GetBoolean(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}-{2}",
entryFilled, orderNumber, objectData));
ZOrder = info.GetInt32(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}-{2}",
entryZOrder, orderNumber, objectData));
Rotation = info.GetInt32(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}-{2}",
entryRotation, orderNumber, objectData));
tipText = info.GetString(String.Format(CultureInfo.InvariantCulture,
"{0}{1}-{2}",
entryTipText, orderNumber, objectData));
// Set the Pen and the Brush, if defined
//if (PenType != DrawingPens.PenType.Generic)
// DrawPen = DrawingPens.SetCurrentPen(PenType);
if (BrushType != FillBrushes.BrushType.NoBrush)
DrawBrush = FillBrushes.SetCurrentBrush(BrushType);
}
#endregion Save/Load methods
#endregion Virtual Functions
#region Other functions
/// <summary>
/// Initialization
/// </summary>
protected void Initialize()
{
}
// private
/// <summary>
/// Copy fields from this instance to cloned instance drawObject.
/// Called from Clone functions of derived classes.
/// </summary>
/// <param name="drawObject">Object being cloned</param>
protected void FillDrawObjectFields(DrawObject drawObject)
{
drawObject.selected = selected;
drawObject.color = color;
drawObject.penWidth = penWidth;
drawObject._endCap = _endCap;
drawObject.ID = ID;
drawObject._brushType = _brushType;
drawObject._penType = _penType;
drawObject.drawBrush = drawBrush;
drawObject.drawpen = drawpen;
drawObject.filled = filled;
drawObject.fillColor = fillColor;
drawObject._rotation = _rotation;
drawObject._center = _center;
drawObject.tipText = tipText;
}
#endregion Other functions
#region IComparable Members
/// <summary>
/// Returns (-1), (0), (+1) to represent the relative Z-order of the object being compared with this object
/// </summary>
/// <param name="obj">DrawObject that is compared to this object</param>
/// <returns> (-1) if the object is less (further back) than this object.
/// (0) if the object is equal to this object (same level graphically).
/// (1) if the object is greater (closer to the front) than this object.</returns>
public int CompareTo(object obj)
{
DrawObject d = obj as DrawObject;
int x = 0;
if (d != null)
if (d.ZOrder == ZOrder)
x = 0;
else if (d.ZOrder > ZOrder)
x = -1;
else
x = 1;
return x;
}
#endregion IComparable Members
}
}
Generated by GNU Enscript 1.6.5.90.