Hi there Stoyan,
At the moment i've got 2 functions in my programm.
One for aligning nodes to another node which consists of this method:
protected void AlignToNearestPoint(Point current, InteractionState ist)
{
if (ist.AdjustmentHandle == 8) // If the node is moved
{
var nearbyNode = Parent.GetNearestNode(current, 30, this);
if (nearbyNode != null)
{
/* If the nearest node has multiple points to connect to, the connection Points
* will be stored here and used later to calculate to which point to snap to.
*/
Point[] targetPoints;
var bounds_nearby_node = nearbyNode.Bounds;
double x_coord = 0;
double y_coord = 0;
var bounds_this_node = this.Bounds;
double x_coord2 = 0;
double y_coord2 = 0;
double dx = 0;
double dy = 0;
if (nearbyNode is If_Shape)
{
// Calculate the point of the nearby node to connect to, default is bottom
x_coord = bounds_nearby_node.X + bounds_nearby_node.Width / 2;
y_coord = bounds_nearby_node.Bottom - bounds_nearby_node.Height / 90;
var targetPoint = new Point(x_coord, y_coord);
// Calculate the point of this node to connect to the nearby node
x_coord2 = bounds_this_node.X + bounds_this_node.Width / 2;
y_coord2 = bounds_this_node.Y;
var pointToSnap = new Point(x_coord2, y_coord2);
double then_x = bounds_nearby_node.X + bounds_nearby_node.Width / 1.43;
double then_y = bounds_nearby_node.Bottom - bounds_nearby_node.Height / 1.18;
Point then_statement = new Point(then_x, then_y);
double else_x = bounds_nearby_node.X + bounds_nearby_node.Width / 1.43;
double else_y = bounds_nearby_node.Bottom - bounds_nearby_node.Height / 2.3;
Point else_statement = new Point(else_x, else_y);
Point bottom = new Point(bounds_nearby_node.X + bounds_nearby_node.Width / 2,
bounds_nearby_node.Bottom - bounds_nearby_node.Height / 90);
double minDistance = double.MaxValue;
targetPoints = new Point[3] { then_statement, else_statement, bottom };
// Check the distance of each targetpoint and the pointToSnap for the closest point
foreach (var s in targetPoints)
{
// Calculate the distancen between the points
double distance_squared = (pointToSnap.X - s.X) * (pointToSnap.X - s.X) + (pointToSnap.Y - s.Y) * (pointToSnap.Y - s.Y);
double distance = Math.Sqrt(distance_squared); //Utilities.Distance(pointToSnap, s);
if (distance < minDistance)
{
minDistance = distance;
targetPoint = s;
}
}
// Calculate the distance of the two points
dx = targetPoint.X - pointToSnap.X;
dy = targetPoint.Y - pointToSnap.Y;
// Move this node by the calculated distance
bounds_this_node.Offset(dx, dy);
SetBounds(bounds_this_node, true, true);
// Lastly, set the connectednode of the nearest node to this node
BR_Shape nearby_Node = nearbyNode as BR_Shape;
nearby_Node.connected_node = this;
}
if (nearbyNode is Action_Shape)
{
// Calculate the point of the nearby node to connect to
x_coord = bounds_nearby_node.X + bounds_nearby_node.Width / 2;
y_coord = bounds_nearby_node.Bottom - bounds_nearby_node.Height / 90;
var targetPoint = new Point(x_coord, y_coord);
// Calculate the point of this node to connect to the nearby node
x_coord2 = bounds_this_node.X + bounds_this_node.Width / 2;
y_coord2 = bounds_this_node.Y;
var pointToSnap = new Point(x_coord2, y_coord2);
// Calculate the distance of the two points
dx = targetPoint.X - pointToSnap.X;
dy = targetPoint.Y - pointToSnap.Y;
// Move this node by the calculated distance
bounds_this_node.Offset(dx, dy);
SetBounds(bounds_this_node, true, true);
// Lastly, set the connectednode of the nearest node to this node
BR_Shape nearby_Node = nearbyNode as BR_Shape;
nearby_Node.connected_node = this;
}
}
}
}
And the second for having a drag and drop preview, which consists of 3 methods:
// This method is called when the cursor enters the corresponding window
private void OnDiagramDragEnter(object sender, DragEventArgs e)
{
// The if statement checks if dragIndicator is empty and if there is a dragNode present
if (dragIndicator == null && e.Data.GetDataPresent(typeof(DraggedNode)))
{
// var data gets present node that is dragable
// var position gets the current position of the node that can be dragged
var data = (DraggedNode)e.Data.GetData(typeof(DraggedNode));
var position = e.GetPosition(this.DocumentPlane);
dragIndicator = (BR_Shape)data.Node.Clone(false);
dragIndicator.Move(position.X, position.Y); // Keeps track of the position
dragIndicator.Opacity = 0.5; // Changes the opacity of the node so that it looks transparent
this.Nodes.Add(dragIndicator); // Node is being added to the diagram - this = the diagram
e.Effects = DragDropEffects.Copy;
e.Handled = true;
}
}
// This method is called when the cursor moves inside the cursor moves inside the corresponding window
public void OnDiagramDragOver(object sender, DragEventArgs e)
{
BR_Shape snap = new BR_Shape();
if (dragIndicator != null)
{
var position = e.GetPosition(this.DocumentPlane);
dragIndicator.Move(position.X, position.Y);
e.Effects = DragDropEffects.Copy;
e.Handled = true;
}
}
// Removes the contents of the dragIndicator, so it can be use again
private void OnNodeCreated(object sender, NodeEventArgs e)
{
if (dragIndicator != null)
{
this.Nodes.Remove(dragIndicator);
dragIndicator = null;
}
}
So, both function are working individually. The thing is, if i drag a node on to my Diagram field i want to be able to snap it directly instead of having to place it in the Diagram field and than to drag it to a different node to snap it.
Is there any way to do this?
Greets,
Sander