/// <summary> /// Called once the move operation has been initialized /// </summary> /// <remarks> /// Calculates which components stay fixed and which nodes will be moved by the user. /// </remarks> private void OnMoveInitialized(object sender, EventArgs eventArgs) { if (layout != null) { CopiedLayoutGraph copy = this.copiedLayoutGraph; var componentNumber = copy.CreateNodeMap(); GraphConnectivity.ConnectedComponents(copy, componentNumber); System.Collections.Generic.HashSet <int> movedComponents = new System.Collections.Generic.HashSet <int>(); System.Collections.Generic.HashSet <Node> selectedNodes = new System.Collections.Generic.HashSet <Node>(); foreach (INode node in movedNodes) { Node copiedNode = copy.GetCopiedNode(node); if (copiedNode != null) { // remember that we nailed down this node selectedNodes.Add(copiedNode); // remember that we are moving this component movedComponents.Add(componentNumber.GetInt(copiedNode)); //Update the position of the node in the CLG to match the one in the IGraph layout.SetCenter(copiedNode, node.Layout.X + node.Layout.Width * 0.5, node.Layout.Y + node.Layout.Height * 0.5); //Actually, the node itself is fixed at the start of a drag gesture layout.SetInertia(copiedNode, 1.0); //Increasing has the effect that the layout will consider this node as not completely placed... // In this case, the node itself is fixed, but it's neighbors will wake up IncreaseHeat(copiedNode, layout, 0.5); } } // there are components that won't be moved - nail the nodes down so that they don't spread apart infinitely foreach (var copiedNode in copy.Nodes) { if (!movedComponents.Contains(componentNumber.GetInt(copiedNode))) { layout.SetInertia(copiedNode, 1); } else { if (!selectedNodes.Contains(copiedNode)) { // make it float freely layout.SetInertia(copiedNode, 0); } } } // dispose the map copy.DisposeNodeMap(componentNumber); //Notify the layout algorithm that there is new work to do... layout.WakeUp(); } }
/// <summary> /// Notifies the layout of the new positions of the interactively moved nodes. /// </summary> private void OnMoving(object sender, InputModeEventArgs inputModeEventArgs) { if (layout != null) { CopiedLayoutGraph copy = this.copiedLayoutGraph; foreach (INode node in movedNodes) { Node copiedNode = copy.GetCopiedNode(node); if (copiedNode != null) { //Update the position of the node in the CLG to match the one in the IGraph layout.SetCenter(copiedNode, node.Layout.GetCenter().X, node.Layout.GetCenter().Y); //Increasing the heat has the effect that the layout will consider these nodes as not completely placed... IncreaseHeat(copiedNode, layout, 0.05); } } //Notify the layout algorithm that there is new work to do... layout.WakeUp(); } }
/// <summary> /// Creates an animation that morphs the layout of all <see cref="ITable"/>s in the graph. /// </summary> /// <seealso cref="TableAnimation"/> /// <seealso cref="ConfigureTableNodeLayout"/> protected virtual IAnimation CreateTableAnimations() { var anims = new List <IAnimation>(); foreach (var node in graph.Nodes) { var table = node.Lookup <ITable>(); if (table != null) { INodeLayout nodeLayout = layoutGraph.GetLayout(layoutGraph.GetCopiedNode(node)); var columnLayout = TableLayoutConfigurator.GetColumnLayout(table, new RectD(nodeLayout.X, nodeLayout.Y, nodeLayout.Width, nodeLayout.Height)); var rowLayout = TableLayoutConfigurator.GetRowLayout(table, new RectD(nodeLayout.X, nodeLayout.Y, nodeLayout.Width, nodeLayout.Height)); anims.Add(new TableAnimation(table, columnLayout, rowLayout)); } } return(anims.CreateParallelAnimation()); }
/// <summary> /// Called once the interactive move is finished. /// </summary> /// <remarks> /// Updates the state of the interactive layout. /// </remarks> private void OnMovedFinished(object sender, InputModeEventArgs inputModeEventArgs) { if (layout != null) { CopiedLayoutGraph copy = this.copiedLayoutGraph; foreach (INode node in movedNodes) { Node copiedNode = copy.GetCopiedNode(node); if (copiedNode != null) { //Update the position of the node in the CLG to match the one in the IGraph layout.SetCenter(copiedNode, node.Layout.GetCenter().X, node.Layout.GetCenter().Y); layout.SetStress(copiedNode, 0); } } foreach (var copiedNode in copy.Nodes) { //Reset the node's inertia to be fixed layout.SetInertia(copiedNode, 1.0); layout.SetStress(copiedNode, 0); } } }