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 } }