using PaintDotNet.Annotation.Enum;
using PaintDotNet.Base;
using PaintDotNet.Base.SettingModel;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.Runtime.Serialization;
using System.Windows.Forms;
namespace PaintDotNet.Annotation
{
public abstract class DrawObject
{
///
/// 目标被选择状态
///
private bool selected;
///
/// 鼠标按下状态, 静态,所有现存的公用
///
public static bool mouseStatus = false;
public static int smallRectangleWidth = MarkPointRect.markPointRectWidth;
public static int MarkpointStyle = MarkPointRect.MarkpointStyle;
public static int MarkpointLineColor = MarkPointRect.MarkpointLineColor;
public static int MarkpointLineWidth = MarkPointRect.MarkpointLineWidth;
public static int MarkpointAreaColor = MarkPointRect.MarkpointAreaColor;
public static bool isFollow = MarkPointRect.isFollow;
///
/// 点集合
///
public List pointArrayList;
///
/// 颜色
///
private Color color;
///
/// 线宽
///
private int penWidth;
///
/// 用于撤消-重做
///
int id;
///
/// 上次使用的属性值
/// 也许可以不用??
///
private static Color lastUsedColor = Color.Black;
///
/// 上次使用的线宽
/// 也许可以不用??
///
private static int lastUsedPenWidth = 1;
///
/// 用于序列化-颜色
///
private const string entryColor = "Color";
///
/// 用于序列化-线宽
///
private const string entryPenWidth = "PenWidth";
///
/// 画板
///
private ISurfaceBox surfaceBox;
///
/// 主要用于区分是标注、测量、视场、其它
///
public DrawClass objectType;
///
/// 用于标注自身是什么工具
///
public DrawToolType drawToolType;
///
/// 外接矩形,或者是计算的矩形
///
protected RectangleF rectangle;
///
/// 起始点
///
public PointF startPoint;
///
/// 物理长度
///
public double length = 0;
///
/// 结束点
///
public PointF endPoint;
///
/// 判断辅助线方向的点
///
public Point judgeP;
///
/// 文本框内容
///
public string textboxMessage;
///
/// 目标点状态 0:添加 1:选择 2:删除
///
public int CompoundRatioSelected;
///
/// 删除状态 0:不删除 1:删除
///
public int delete;
public bool isLocked = false;
public virtual RectangleF Rectangle
{
get
{
return rectangle;
}
set
{
rectangle = value;
OnPropertyChanged();
}
}
public virtual double Height
{ get; set; }
public virtual double Width
{ get; set; }
///
/// 公开出去的自定义事件
/// 当对象本身属性有所改变的时候
/// 比如边长,原点等有变化
///
public event EventHandler PropertyChanged;
protected virtual void OnPropertyChanged()
{
if (PropertyChanged != null)
{
PropertyChanged(this, EventArgs.Empty);
}
}
///
/// 选中状态改变的事件
///
public event Action SelectedChanged;
public ISurfaceBox ISurfaceBox
{
set
{
this.surfaceBox = value;
}
get
{
return this.surfaceBox;
}
}
public DrawObject()
{
id = this.GetHashCode();
}
///
/// Selection flag
///
public bool Selected
{
get
{
return selected;
}
set
{
selected = value;
SelectedChanged?.Invoke();
}
}
///
/// Color
///
public Color Color
{
get
{
return color;
}
set
{
color = value;
}
}
///
/// Pen width
///
public int PenWidth
{
get
{
return penWidth;
}
set
{
penWidth = value;
}
}
///
/// Number of handles
///
public virtual int HandleCount
{
get
{
return 0;
}
}
///
/// Object ID
///
public int ID
{
get { return id; }
set { id = value; }
}
///
/// Last used color
///
public static Color LastUsedColor
{
get
{
return lastUsedColor;
}
set
{
lastUsedColor = value;
}
}
///
/// Last used pen width
///
public static int LastUsedPenWidth
{
get
{
return lastUsedPenWidth;
}
set
{
lastUsedPenWidth = value;
}
}
#region 虚函数
///
/// Clone this instance.
///
public abstract DrawObject Clone();
public virtual DrawObject Clone(ISurfaceBox ISurfaceBox) { return null; }
///
/// Draw object
///
///
public virtual void Draw(Graphics g)
{
}
public abstract RectangleF GetBoundingBox();
///
/// Get handle pointscroll by 1-based number
///
///
///
public virtual PointF GetHandle(int handleNumber)
{
return new PointF(0, 0);
}
///
/// Get handle rectangle by 1-based number
///
///
///
public virtual Rectangle GetHandleRectangle(int handleNumber)
{
PointF point = GetHandle(handleNumber);
int tempLess;
int tempPlus;
if (isFollow)
{
if (smallRectangleWidth == 0)
{
tempLess = (int)(6 * (this.surfaceBox.ScaleRatio < 1 ? 1 / this.surfaceBox.ScaleRatio : 1));
tempPlus = (int)(12 * (this.surfaceBox.ScaleRatio < 1 ? 1 / this.surfaceBox.ScaleRatio : 1));
}
else
{
tempLess = (int)((smallRectangleWidth / 2) * (this.surfaceBox.ScaleRatio < 1 ? 1 / this.surfaceBox.ScaleRatio : 1));
tempPlus = (int)(smallRectangleWidth * (this.surfaceBox.ScaleRatio < 1 ? 1 / this.surfaceBox.ScaleRatio : 1));
}
}
else
{
if (smallRectangleWidth == 0)
{
tempLess = (int)(6 * 1);
tempPlus = (int)(12 * 1);
}
else
{
tempLess = (int)((smallRectangleWidth / 2) * 1);
tempPlus = (int)(smallRectangleWidth * 1);
}
}
return new Rectangle((int)(point.X - tempLess), (int)(point.Y - tempLess), tempPlus, tempPlus);
}
///
/// Get handle rectangle by 1-based number
///
///
///
public virtual PointF[] GetHandlePoint(int handleNumber)
{
PointF point = GetHandle(handleNumber);
int tempLess;
int tempPlus;
if (isFollow)
{
if (smallRectangleWidth == 0)
{
tempLess = (int)(6 * (this.surfaceBox.ScaleRatio < 1 ? 1 / this.surfaceBox.ScaleRatio : 1));
tempPlus = (int)(12 * (this.surfaceBox.ScaleRatio < 1 ? 1 / this.surfaceBox.ScaleRatio : 1));
}
else
{
tempLess = (int)((smallRectangleWidth / 2) * (this.surfaceBox.ScaleRatio < 1 ? 1 / this.surfaceBox.ScaleRatio : 1));
tempPlus = (int)(smallRectangleWidth * (this.surfaceBox.ScaleRatio < 1 ? 1 / this.surfaceBox.ScaleRatio : 1));
}
}
else {
if (smallRectangleWidth == 0)
{
tempLess = (int)(6 * 1);
tempPlus = (int)(12 * 1);
}
else
{
tempLess = (int)((smallRectangleWidth / 2) * 1);
tempPlus = (int)(smallRectangleWidth * 1);
}
}
PointF point1 = new PointF(point.X,point.Y - tempLess);
PointF point2 = new PointF(point.X - tempLess, point.Y + tempLess);
PointF point3 = new PointF(point.X + tempLess, point.Y + tempLess);
return new PointF[3] { point1,point2,point3 };
}
///
/// Draw tracker for selected object
///
///
public virtual void DrawTracker(Graphics g)
{
if (!Selected)
return;
SolidBrush brush = new SolidBrush(Color.FromArgb(MarkpointAreaColor));
Pen pen = new Pen(Color.FromArgb(MarkpointLineColor),MarkpointLineWidth);
for (int i = 1; i <= HandleCount; i++)
{
switch (MarkpointStyle)
{
case 0:
g.FillRectangle(brush, GetHandleRectangle(i));
g.DrawRectangle(pen, GetHandleRectangle(i));
break;
case 1:
g.FillEllipse(brush, GetHandleRectangle(i));
g.DrawEllipse(pen, GetHandleRectangle(i));
break;
case 2:
g.FillPolygon(brush, GetHandlePoint(i));
g.DrawPolygon(pen, GetHandlePoint(i));
break;
}
}
brush.Dispose();
pen.Dispose();
}
///
/// Hit test.
/// Return value: -1 - no hit
/// 0 - hit anywhere
/// > 1 - handle number
///
///
///
public virtual int HitTest(Point point)
{
return -1;
}
///
/// 获取鼠标按下时的坐标
///
///
public virtual void MouseDownPoint(Point point)
{
}
public virtual void MouseUp(bool up)
{
}
///
/// Test whether pointscroll is inside of the object
///
///
///
protected virtual bool PointInObject(Point point)
{
return false;
}
///
/// Get cursor for the handle
///
///
///
public virtual Cursor GetHandleCursor(int handleNumber)
{
return Cursors.Default;
}
///
/// Test whether object intersects with rectangle
///
///
///
public virtual bool IntersectsWith(Rectangle rectangle)
{
return false;
}
///
/// Move object
///
///
///
public virtual void Move(int deltaX, int deltaY)
{
OnPropertyChanged();
}
///
/// Move handle to the pointscroll
///
///
///
public virtual void MoveHandleTo(Point point, int handleNumber)
{
OnPropertyChanged();
}
public virtual void MoveHandleTo(PointF point, int handleNumber)
{
OnPropertyChanged();
}
///
/// Dump (for debugging)
///
public virtual void Dump()
{
Trace.WriteLine(this.GetType().Name);
Trace.WriteLine("Selected = " +
selected.ToString(CultureInfo.InvariantCulture)
+ " ID = " + id.ToString(CultureInfo.InvariantCulture));
}
///
/// Normalize object.
/// Call this function in the end of object resizing.
///
public virtual void Normalize()
{
this.Rectangle = GetNormalizedRectangleF(this.Rectangle);
}
public static RectangleF GetNormalizedRectangleF(RectangleF r)
{
return GetNormalizedRectangleF(r.X, r.Y, r.X + r.Width, r.Y + r.Height);
}
public static RectangleF GetNormalizedRectangleF(PointF p1, PointF p2)
{
return GetNormalizedRectangleF(p1.X, p1.Y, p2.X, p2.Y);
}
public static RectangleF GetNormalizedRectangleF(float x1, float y1, float x2, float y2)
{
if (x2 < x1)
{
float tmp = x2;
x2 = x1;
x1 = tmp;
}
if (y2 < y1)
{
float tmp = y2;
y2 = y1;
y1 = tmp;
}
return new RectangleF(x1, y1, (x2 - x1), (y2 - y1));
}
public static Rectangle GetNormalizedRectangle(RectangleF r)
{
return GetNormalizedRectangle(r.X, r.Y, r.X + r.Width, r.Y + r.Height);
}
public static Rectangle GetNormalizedRectangle(PointF p1, PointF p2)
{
return GetNormalizedRectangle(p1.X, p1.Y, p2.X, p2.Y);
}
public static Rectangle GetNormalizedRectangle(float x1, float y1, float x2, float y2)
{
if (x2 < x1)
{
float tmp = x2;
x2 = x1;
x1 = tmp;
}
if (y2 < y1)
{
float tmp = y2;
y2 = y1;
y1 = tmp;
}
return new Rectangle((int)x1, (int)y1, (int)(x2 - x1), (int)(y2 - y1));
}
///
/// Save object to serialization stream
///
///
///
public virtual void SaveToStream(SerializationInfo info, int orderNumber)
{
info.AddValue(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}",
entryColor, orderNumber),
Color.ToArgb());
info.AddValue(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}",
entryPenWidth, orderNumber),
PenWidth);
}
///
/// Load object from serialization stream
///
///
///
public virtual void LoadFromStream(SerializationInfo info, int orderNumber)
{
int n = info.GetInt32(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}",
entryColor, orderNumber));
Color = Color.FromArgb(n);
PenWidth = info.GetInt32(
String.Format(CultureInfo.InvariantCulture,
"{0}{1}",
entryPenWidth, orderNumber));
id = this.GetHashCode();
}
///
/// 用于返回组成标注/测量/视场的所有的点的集合
/// 暂时没有想到有特殊的数据需要处理,想到再说
///
///
public virtual List GetPoints()
{
return null;
}
public virtual ParentStyleModel GetStyle()
{
return null;
}
public virtual string GetContent()
{
return "";
}
#endregion
#region 其它方法
///
/// Initialization
///
protected void Initialize()
{
color = lastUsedColor;
penWidth = LastUsedPenWidth;
}
///
/// Copy fields from this instance to cloned instance drawObject.
/// Called from Clone functions of derived classes.
///
protected void FillDrawObjectFields(DrawObject drawObject)
{
drawObject.selected = this.selected;
drawObject.color = this.color;
drawObject.penWidth = this.penWidth;
drawObject.ID = this.ID;
}
#endregion
}
}