using System; using System.Windows.Forms; using System.Drawing; using System.Diagnostics; using System.Globalization; using System.Drawing.Drawing2D; using System.Runtime.Serialization; namespace DrawTools { /// /// Line graphic object /// class DrawLine : DrawTools.DrawObject { private Point startPoint; private Point endPoint; private const string entryStart = "Start"; private const string entryEnd = "End"; /// /// Graphic objects for hit test /// private GraphicsPath areaPath = null; private Pen areaPen = null; private Region areaRegion = null; public DrawLine() : this(0, 0, 1, 0) { } public DrawLine(int x1, int y1, int x2, int y2) : base() { startPoint.X = x1; startPoint.Y = y1; endPoint.X = x2; endPoint.Y = y2; Initialize(); } /// /// Clone this instance /// public override DrawObject Clone() { DrawLine drawLine = new DrawLine(); drawLine.startPoint = this.startPoint; drawLine.endPoint = this.endPoint; FillDrawObjectFields(drawLine); return drawLine; } public override void Draw(Graphics g) { g.SmoothingMode = SmoothingMode.AntiAlias; Pen pen = new Pen(Color, PenWidth); g.DrawLine(pen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); pen.Dispose(); } public override int HandleCount { get { return 2; } } /// /// Get handle point by 1-based number /// /// /// public override Point GetHandle(int handleNumber) { if ( handleNumber == 1 ) return startPoint; else return endPoint; } /// /// Hit test. /// Return value: -1 - no hit /// 0 - hit anywhere /// > 1 - handle number /// /// /// public override int HitTest(Point point) { if ( Selected ) { for ( int i = 1; i <= HandleCount; i++ ) { if ( GetHandleRectangle(i).Contains(point) ) return i; } } if ( PointInObject(point) ) return 0; return -1; } protected override bool PointInObject(Point point) { CreateObjects(); return AreaRegion.IsVisible(point); } public override bool IntersectsWith(Rectangle rectangle) { CreateObjects(); return AreaRegion.IsVisible(rectangle); } public override Cursor GetHandleCursor(int handleNumber) { switch ( handleNumber ) { case 1: case 2: return Cursors.SizeAll; default: return Cursors.Default; } } public override void MoveHandleTo(Point point, int handleNumber) { if ( handleNumber == 1 ) startPoint = point; else endPoint = point; Invalidate(); } public override void Move(int deltaX, int deltaY) { startPoint.X += deltaX; startPoint.Y += deltaY; endPoint.X += deltaX; endPoint.Y += deltaY; Invalidate(); } public override void SaveToStream(System.Runtime.Serialization.SerializationInfo info, int orderNumber) { info.AddValue( String.Format(CultureInfo.InvariantCulture, "{0}{1}", entryStart, orderNumber), startPoint); info.AddValue( String.Format(CultureInfo.InvariantCulture, "{0}{1}", entryEnd, orderNumber), endPoint); base.SaveToStream (info, orderNumber); } public override void LoadFromStream(SerializationInfo info, int orderNumber) { startPoint = (Point)info.GetValue( String.Format(CultureInfo.InvariantCulture, "{0}{1}", entryStart, orderNumber), typeof(Point)); endPoint = (Point)info.GetValue( String.Format(CultureInfo.InvariantCulture, "{0}{1}", entryEnd, orderNumber), typeof(Point)); base.LoadFromStream (info, orderNumber); } /// /// Invalidate object. /// When object is invalidated, path used for hit test /// is released and should be created again. /// protected void Invalidate() { if ( AreaPath != null ) { AreaPath.Dispose(); AreaPath = null; } if ( AreaPen != null ) { AreaPen.Dispose(); AreaPen = null; } if ( AreaRegion != null ) { AreaRegion.Dispose(); AreaRegion = null; } } /// /// Create graphic objects used from hit test. /// protected virtual void CreateObjects() { if ( AreaPath != null ) return; // Create path which contains wide line // for easy mouse selection AreaPath = new GraphicsPath(); AreaPen = new Pen(Color.Black, 7); AreaPath.AddLine(startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); AreaPath.Widen(AreaPen); // Create region from the path AreaRegion = new Region(AreaPath); } protected GraphicsPath AreaPath { get { return areaPath; } set { areaPath = value; } } protected Pen AreaPen { get { return areaPen; } set { areaPen = value; } } protected Region AreaRegion { get { return areaRegion; } set { areaRegion = value; } } } }