This class always draws new nodes when Ctrl is pressed, even if over a handle, and otherwise lets you modify selected nodes:
class RectanglesBehavior : DrawShapesBehavior
{
public RectanglesBehavior(Diagram diagram) : base(diagram)
{
}
public override InteractionState StartDraw(Point point)
{
Diagram.ModifierKeyActions.Control = ModifierKeyAction.None;
if (Keyboard.Modifiers == ModifierKeys.Control)
return new InteractionState(new ShapeNode(Diagram), null, Action.Create);
var selected = Diagram.ActiveItem as ShapeNode;
if (selected != null )
{
var handle = selected.HitTestHandle(point);
if (handle != null)
return new InteractionState(selected, handle, Action.Modify);
}
/*
var rect = NearestRect(point);
if (rect != null)
{
var handlesStyle = rect.HandlesStyle;
rect.HandlesStyle = HandlesStyle.SquareHandles2;
var handle = rect.HitTestHandle(point);
rect.HandlesStyle = handlesStyle;
if (handle != null)
return new InteractionState(rect, handle, Action.Modify);
}*/
return base.StartDraw(point);
}
/*public override CursorHint SetMouseCursor(Point point, out bool startInteraction)
{
return base.SetMouseCursor(point, out startInteraction);
}*/
/*protected override void OnMouseUp(Point mousePosition, MindFusion.Diagramming.Wpf.MouseButton mouseButton)
{
base.OnMouseUp(mousePosition, mouseButton);
}*/
DiagramNode NearestRect(Point point)
{
DiagramNode nearest = null;
double minDist = double.MaxValue;
foreach (var node in Diagram.Nodes)
{
if (node.Locked)
continue;
var dist = DistToRect(point, node.Bounds);
if (dist < minDist)
{
minDist = dist;
nearest = node;
}
}
return nearest;
}
double DistToRect(Point point, Rect rect)
{
var v = new[]
{
new Point(rect.Left, rect.Top),
new Point(rect.Right, rect.Top),
new Point(rect.Right, rect.Bottom),
new Point(rect.Left, rect.Bottom),
};
double minDist = double.MaxValue;
for (var i = 0; i < 4; i++)
{
var v1 = v[i];
var v2 = v[(i + 1) % 4];
var dist = MindFusion.Utilities.DistToLineSegment(point, v1, v2);
if (dist < minDist)
minDist = dist;
}
return minDist;
}
}
diagram.ModifierKeyActions.Control = ModifierKeyAction.None;
diagram.CustomBehavior = new RectanglesBehavior(diagram);
With that, you will not need the MouseDown override from your other forum post. If you uncomment the var rect = NearestRect(point) part, it will also let you resize non-selected nodes by grabbing their border. If you want different priorities for handles / border dragging / creation, just rearrange the code.
You might want to override the SetMouseCursor method too, so it does not show resize cursors when Ctrl is down over a handle. You could also move your selection code from previous posts to the MouseUp override in custom behavior class, to keep all the interaction logic together.
Regards,
Slavcho