using System.Drawing; using System.Windows.Forms; namespace CraftSynth.ImageEditor { /// /// Connector tool (a Connector is a series of connected straight lines where each line is drawn individually and at least one of the ends is anchored to another object) /// internal class ToolConnector : ToolObject { public ToolConnector() { Cursor = new Cursor(GetType(), "Pencil.cur"); } private DrawConnector newConnector; private bool _drawingInProcess = false; // Set to true when drawing /// /// Left mouse button is pressed /// /// /// public override void OnMouseDown(DrawArea drawArea, MouseEventArgs e) { if (e.Button == MouseButtons.Right) { _drawingInProcess = false; newConnector = null; } else { Point p = drawArea.BackTrackMouse(new Point(e.X, e.Y)); int objectID = -1; p = TestForConnection(drawArea, p, out objectID); if (_drawingInProcess == false) { newConnector = new DrawConnector(p.X, p.Y, p.X + 1, p.Y + 1, drawArea.LineColor, drawArea.LineWidth, drawArea.PenType, drawArea.EndCap); newConnector.EndPoint = new Point(p.X + 1, p.Y + 1); if (objectID > -1) { newConnector.StartIsAnchored = true; newConnector.StartObjectId = objectID; } AddNewObject(drawArea, newConnector); _drawingInProcess = true; } else { // Drawing is in process, so simply add a new point newConnector.AddPoint(p); newConnector.EndPoint = p; if (objectID > -1) { newConnector.EndIsAnchored = true; newConnector.EndObjectId = objectID; _drawingInProcess = false; } } } } private static Point TestForConnection(DrawArea drawArea, Point p, out int objectID) { // Determine if within 5 pixels of a connection point // Step 1: see if a 5 x 5 rectangle centered on the mouse cursor intersects with an object // Step 2: If it does, then see if there is a connection point within the rectangle // Step 3: If there is, move the point to the connection point, record the object's id in the connector // objectID = -1; Rectangle testRectangle = new Rectangle(p.X - 2, p.Y - 2, 5, 5); int al = drawArea.TheLayers.ActiveLayerIndex; bool connectionHere = false; Point h = new Point(-1, -1); GraphicsList gl = drawArea.TheLayers[al].Graphics; for (int i = 1; i < gl.Count; i++) { if (gl[i].IntersectsWith(testRectangle)) { DrawObject obj = (DrawObject)gl[i]; for (int j = 1; j < obj.HandleCount + 1; j++) { h = obj.GetHandle(j); if (testRectangle.Contains(h)) { connectionHere = true; p = h; objectID = obj.ID; // obj.DrawConnection(drawArea., j); break; } } } if (connectionHere) break; } return p; } /// /// Mouse move - resize new polygon /// /// /// public override void OnMouseMove(DrawArea drawArea, MouseEventArgs e) { drawArea.Cursor = Cursor; if (e.Button != MouseButtons.Left) return; if (newConnector == null) return; // precaution Point point = drawArea.BackTrackMouse(new Point(e.X, e.Y)); int objectID; point = TestForConnection(drawArea, point, out objectID); // move last point newConnector.MoveHandleTo(point, newConnector.HandleCount); drawArea.Refresh(); if (objectID > -1) { newConnector.EndIsAnchored = true; newConnector.EndObjectId = objectID; _drawingInProcess = false; } } #region Destruction private bool _disposed = false; protected override void Dispose(bool disposing) { if (!this._disposed) { if (disposing) { // Free any managed objects here. if (this.newConnector != null) { this.newConnector.Dispose(); } } // Free any unmanaged objects here. this._disposed = true; } base.Dispose(disposing); } ~ToolConnector() { this.Dispose(false); } #endregion } }