/// <summary> /// Finishes the drag and updates the angle of the rotated node. /// </summary> public void DragFinished(IInputModeContext context, PointD originalLocation, PointD newLocation) { var vector = (newLocation - rotationCenter).Normalized; var angle = CalculateAngle(vector); if (ShouldSnap(context)) { angle = SnapAngle(context, angle); } SetAngle(context, angle); // Switch width / height for 'vertical' rotations // Note that other parts of the application need support for this feature, too. var graph = context.GetGraph(); if (graph == null) { return; } var portContext = new DelegatingContext(context); foreach (var portHandle in portHandles) { portHandle.DragFinished(portContext, originalLocation, newLocation); } portHandles.Clear(); // Workaround: if the OrthogonalEdgeEditingContext is used to keep the edges orthogonal, it is not allowed // to change that edges manually. Therefore, we explicitly finish the OrthogonalEdgeEditingContext here and // then call the edge router. var edgeEditingContext = context.Lookup <OrthogonalEdgeEditingContext>(); if (edgeEditingContext != null && edgeEditingContext.IsInitialized) { edgeEditingContext.DragFinished(); } if (reshapeHandler != null) { reshapeHandler.ReshapeFinished(context, node.Layout.ToRectD(), node.Layout.ToRectD()); } if (compoundEdit != null) { compoundEdit.Commit(); } nodeAngles = null; ClearSameAngleHighlights(context); }
/// <summary> /// Initializes the drag. /// </summary> public void InitializeDrag(IInputModeContext context) { var imc = context.Lookup <IModelItemCollector>(); if (imc != null) { imc.Add(node); } rotationCenter = node.Layout.GetCenter(); initialAngle = GetAngle(); var graph = context.Lookup <IGraph>(); if (graph != null) { compoundEdit = graph.BeginEdit("Change Rotation Angle", "Change Rotation Angle"); } portHandles.Clear(); var portContext = new DelegatingContext(context); foreach (var port in node.Ports) { var portHandle = new DummyPortLocationModelParameterHandle(port); portHandle.InitializeDrag(portContext); portHandles.Add(portHandle); } if (reshapeHandler != null) { reshapeHandler.InitializeReshape(context); } // Collect other visible nodes and their angles if (SnapToSameAngleDelta > 0) { var canvas = context.CanvasControl; var rotatedNodes = canvas.GetCanvasObjects() .Select(co => co.UserObject) // only collect nodes .OfType <INode>() // ... that are in the viewport .Where(n => canvas.Viewport.Intersects(n.Layout.ToRectD())) // ... and can be rotated .Where(n => n.Style is RotatableNodeStyleDecorator) // ... and are not *this* node .Where(n => n != node); // Group nodes by identical angles nodeAngles = rotatedNodes.GroupBy(n => ((RotatableNodeStyleDecorator)n.Style).Angle) .Select(nodes => Tuple.Create(nodes.Key, nodes.ToList().AsEnumerable())).ToList(); } }
/// <summary> /// Applies the new node layout. /// </summary> public void DragFinished(IInputModeContext inputModeContext, PointD originalLocation, PointD newLocation) { var newLayout = SetNodeLocationAndSize(inputModeContext, dummyLocation, dummySize); var portContext = new DelegatingContext(inputModeContext); foreach (var portHandle in portHandles) { portHandle.DragFinished(portContext, originalLocation, newLocation); } portHandles.Clear(); if (reshapeHandler != null) { // if there is a reshape handler: // ensure proper handling of a parent group node reshapeHandler.ReshapeFinished(inputModeContext, initialRect, newLayout); } }
/// <summary> /// Restores the original node layout. /// </summary> public void CancelDrag(IInputModeContext inputModeContext, PointD originalLocation) { SetNodeLocationAndSize(inputModeContext, initialLayout.GetAnchorLocation(), initialLayout.GetSize()); var portContext = new DelegatingContext(inputModeContext); foreach (var portHandle in portHandles) { portHandle.CancelDrag(portContext, originalLocation); } portHandles.Clear(); if (reshapeHandler != null) { // if there is a reshape handler: // ensure proper handling of a parent group node reshapeHandler.CancelReshape(inputModeContext, initialRect); } }
/// <summary> /// Cancels the drag and cleans up. /// </summary> public void CancelDrag(IInputModeContext context, PointD originalLocation) { SetAngle(context, initialAngle); var portContext = new DelegatingContext(context); foreach (var portHandle in portHandles) { portHandle.CancelDrag(portContext, originalLocation); } portHandles.Clear(); if (reshapeHandler != null) { reshapeHandler.CancelReshape(context, node.Layout.ToRectD()); } if (compoundEdit != null) { compoundEdit.Cancel(); } nodeAngles = null; ClearSameAngleHighlights(context); }
/// <summary> /// Stores the initial layout of the node in case the user cancels the resizing. /// </summary> /// <param name="inputModeContext"></param> public void InitializeDrag(IInputModeContext inputModeContext) { if (reshapeHandler != null) { // if there is a reshape handler: initialize to // ensure proper handling of a parent group node reshapeHandler.InitializeReshape(inputModeContext); } initialLayout.Reshape(GetNodeBasedOrientedRectangle()); dummyLocation = initialLayout.GetAnchorLocation(); dummySize = initialLayout.GetSize(); initialRect = node.Layout.ToRectD(); portHandles.Clear(); var portContext = new DelegatingContext(inputModeContext); foreach (var port in node.Ports) { var portHandle = new DummyPortLocationModelParameterHandle(port); portHandle.InitializeDrag(portContext); portHandles.Add(portHandle); } }
/// <summary> /// Updates the node according to the moving handle. /// </summary> public void HandleMove(IInputModeContext context, PointD originalLocation, PointD newLocation) { // calculate the angle var vector = (newLocation - rotationCenter).Normalized; var angle = CalculateAngle(vector); if (ShouldSnap(context)) { angle = SnapAngle(context, angle); } SetAngle(context, angle); var portContext = new DelegatingContext(context); foreach (var portHandle in portHandles) { portHandle.HandleMove(portContext, originalLocation, newLocation); } if (reshapeHandler != null) { reshapeHandler.HandleReshape(context, node.Layout.ToRectD(), node.Layout.ToRectD()); } }
/// <summary> /// Adjusts the node location and size according to the new handle location. /// </summary> public void HandleMove(IInputModeContext inputModeContext, PointD originalLocation, PointD newLocation) { // calculate how much the handle was moved var upNormal = new PointD(-initialLayout.UpY, initialLayout.UpX); var deltaW = GetWidthDelta(originalLocation, newLocation, upNormal); var up = initialLayout.GetUp(); var deltaH = GetHeightDelta(originalLocation, newLocation, up); // add one or two times delta to the width to expand the node right and left dummySize = new SizeD( initialLayout.Width + deltaW * (symmetricResize ? 2 : 1), initialLayout.Height + deltaH * (symmetricResize ? 2 : 1)); // Calculate the new location. // Depending on our handle position, a different corner of the node should stay fixed. if (symmetricResize) { var dx = upNormal.X * deltaW + up.X * deltaH; var dy = upNormal.Y * deltaW + up.Y * deltaH; dummyLocation = initialLayout.GetAnchorLocation() - new PointD(dx, dy); } else { var w = dummySize.Width - initialLayout.Width; var h = dummySize.Height - initialLayout.Height; switch (position) { case HandlePositions.NorthWest: dummyLocation = initialLayout.GetAnchorLocation() - new PointD(-up.Y * w, up.X * w); break; case HandlePositions.South: case HandlePositions.SouthWest: case HandlePositions.West: dummyLocation = initialLayout.GetAnchorLocation() - new PointD(up.X * h - up.Y * w, up.Y * h + up.X * w); break; case HandlePositions.SouthEast: dummyLocation = initialLayout.GetAnchorLocation() - new PointD(up.X * h, up.Y * h); break; // case HandlePositions.North: // case HandlePositions.NorthEast: // case HandlePositions.East: default: dummyLocation = initialLayout.GetAnchorLocation(); break; } } var newLayout = SetNodeLocationAndSize(inputModeContext, dummyLocation, dummySize); var portContext = new DelegatingContext(inputModeContext); foreach (var portHandle in portHandles) { portHandle.HandleMove(portContext, dummyLocation, newLocation); } if (reshapeHandler != null) { // if there is a reshape handler: // ensure proper handling of a parent group node reshapeHandler.HandleReshape(inputModeContext, initialRect, newLayout); } }