public bool MouseMove(GraphicView activeView, System.Windows.Forms.MouseEventArgs e)
{
bool ret = true;
paintMagnets.Clear();
pickItems(e);
recalcPrimaryDependant(activeView);
// Check snap to acquired magnets
points.Snap(activeView, e);
lines.Snap(activeView, e);
// Get max snap Magnet (the one closer to the mouse position)
Magnet bestMagnet;
float snap, bestSnap, bestPointSnap = points.GetBestSnap(out bestMagnet);
if (bestMagnet == null)
bestSnap = lines.GetBestSnap(out bestMagnet);
else
bestSnap = bestPointSnap;
// Update CurrentLine's positions if mouse moved over any of it's joints (if LineMagnet has a Line)
if (lines.CurrentLine != null && bestMagnet != null && bestMagnet is PointMagnet &&
lines.CurrentLine.Line != null && ((PointMagnet)bestMagnet).Joint != null)
{
Joint newJoint = ((PointMagnet)bestMagnet).Joint;
if (newJoint == lines.CurrentLine.Line.I || newJoint == lines.CurrentLine.Line.J)
lines.CurrentLine.Position = newJoint.Position;
}
#region Intersection
// Check intersections between LineMagnets. If any, create corresponding Magnet
if (lines.CurrentLine != null && bestMagnet is LineMagnet && bestMagnet != lines.CurrentLine)
{
PointMagnet intersectionMagnet = createIntersection(lines.CurrentLine, bestMagnet as LineMagnet, activeView, e);
if (intersectionMagnet != null)
{
snap = intersectionMagnet.Snap(activeView, e.Location) + SnapEpsilon;
if (snap < SnapViewDistance)
{
// Paint helper line
paintMagnets.Add(bestMagnet);
// Paint intersection
paintMagnets.Add(intersectionMagnet);
}
if (snap < bestPointSnap && snap < EffectiveSnapDistance)
{
bestSnap = snap;
bestMagnet = intersectionMagnet;
}
}
}
#endregion
#region Midpoint
// Create midpoint magnet (if mouse is close to a Line)
foreach (Magnet m in lines)
{
PointMagnet midMagnet = createMidPoint(m as LineMagnet, activeView, e);
if (midMagnet != null)
{
snap = midMagnet.Snap(activeView, e.Location) + SnapEpsilon;
if (snap < bestPointSnap && snap < EffectiveSnapDistance)
{
bestSnap = snap;
bestMagnet = midMagnet;
}
}
}
#endregion
#region Perpendicular point
// Create perpendicular magnets (if mouse is close to a line)
PointMagnet perpMagnet = createPerpendicularMagnet(bestMagnet as LineMagnet, activeView, e);
if (perpMagnet != null)
{
snap = perpMagnet.Snap(activeView, e.Location) + SnapEpsilon;
if (snap < (bestPointSnap - SnapEpsilon) && snap < EffectiveSnapDistance)
{
bestSnap = snap;
bestMagnet = perpMagnet;
}
}
#endregion
#region Interesting Distance
// If following a LineMagnet, then set next interesting distance as a PointMagnet
PointMagnet distMagnet = createInterestingDistance(bestMagnet as LineMagnet, activeView, e);
if (distMagnet != null)
{
snap = distMagnet.Snap(activeView, e.Location) + SnapEpsilon;
if (snap < bestPointSnap)
{
bestSnap = snap;
bestMagnet = distMagnet;
}
}
#endregion
// Choose magnets to paint
if ((bestMagnet is LineMagnet) && (lines.CurrentLine == null))
lines.CurrentLine = (LineMagnet)bestMagnet;
else if ((bestMagnet != null) && !bestMagnet.Equals(lines.CurrentLine))
paintMagnets.Add(bestMagnet);
// Set the Magnet to snap to if the user clicks the mouse
snapMagnet = null;
if (bestMagnet != null)
{
if (bestMagnet is PointMagnet && bestMagnet.LastSnapFitness < EffectiveSnapDistance)
snapMagnet = bestMagnet;
else if (lines.CurrentLine != null)
snapMagnet = lines.CurrentLine;
else if (bestMagnet is LineMagnet)
snapMagnet = bestMagnet;
}
else
{
area.Snap(activeView, e.Location);
snapMagnet = (Magnet)area.Clone();
}
// TODO: Probably change the IsActive property to some enum, so as to activate snapping to
// specific objects only (i.e. Joint snapping when CommandServices.GetJoint() is working)
return ret;
}