Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Place suggested node wrt node height and width #11173

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions src/DynamoCore/Models/DynamoModelCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,10 @@ private void CreateAndConnectNodeImpl(CreateAndConnectNodeCommand command)
using (CurrentWorkspace.UndoRecorder.BeginActionGroup())
{
var newNode = CreateNodeFromNameOrType(command.ModelGuid, command.NewNodeName);

newNode.X = command.X;
newNode.Y = command.Y;

var existingNode = CurrentWorkspace.GetModelInternal(command.ModelGuids.ElementAt(1)) as NodeModel;

if(newNode == null || existingNode == null) return;
Expand Down Expand Up @@ -124,6 +126,49 @@ private void CreateAndConnectNodeImpl(CreateAndConnectNodeCommand command)
}
}

private void PlaceAndConnectNodeImpl(PlaceAndConnectNodeCommand command)
{
using (CurrentWorkspace.UndoRecorder.BeginActionGroup())
{
var newNode = CurrentWorkspace.GetModelInternal(command.ModelGuids.ElementAt(0)) as NodeModel;
var existingNode = CurrentWorkspace.GetModelInternal(command.ModelGuids.ElementAt(1)) as NodeModel;

if (newNode == null || existingNode == null) return;

newNode.X = command.X;
newNode.Y = command.Y;

PortModel inPortModel, outPortModel;
if (command.IsDownstreamNode)
{
// Connect output port of Existing Node to input port of New node
outPortModel = existingNode.OutPorts[command.OutputPortIndex];
inPortModel = newNode.InPorts[command.InputPortIndex];
}
else
{
// Connect output port of New Node to input port of existing node
outPortModel = newNode.OutPorts[command.OutputPortIndex];
inPortModel = existingNode.InPorts[command.InputPortIndex];
}

var models = GetConnectorsToAddAndDelete(inPortModel, outPortModel);

foreach (var modelPair in models)
{
switch (modelPair.Value)
{
case UndoRedoRecorder.UserAction.Creation:
CurrentWorkspace.UndoRecorder.RecordCreationForUndo(modelPair.Key);
break;
case UndoRedoRecorder.UserAction.Deletion:
CurrentWorkspace.UndoRecorder.RecordDeletionForUndo(modelPair.Key);
break;
}
}
}
}

private NodeModel GetNodeFromCommand(CreateNodeCommand command)
{
if (command.Node != null)
Expand Down
100 changes: 100 additions & 0 deletions src/DynamoCore/Models/RecordableCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,9 @@ internal static RecordableCommand Deserialize(XmlElement element)
case "CreateAndConnectNodeCommand":
command = CreateAndConnectNodeCommand.DeserializeCore(element);
break;
case "PlaceAndConnectNodeCommand":
command = PlaceAndConnectNodeCommand.DeserializeCore(element);
break;
}

if (null != command)
Expand Down Expand Up @@ -921,6 +924,103 @@ internal static CreateAndConnectNodeCommand DeserializeCore(XmlElement element)

}

/// <summary>
/// A command used to create a new upstream/downstream node and connect
/// it to an existing node in a single step
/// </summary>
[DataContract]
public class PlaceAndConnectNodeCommand : ModelBasedRecordableCommand
{

#region Public Class Methods

/// <summary>
/// Creates a new PlaceAndConnectNodeCommand with the given inputs
/// </summary>
/// <param name="newNodeGuid"></param>
/// <param name="existingNodeGuid"></param>
/// <param name="outPortIndex"></param>
/// <param name="inPortIndex"></param>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="isDownstreamNode">
/// true if new node is created as downstream node wrt the existing node; false otherwise
/// </param>
public PlaceAndConnectNodeCommand(Guid newNodeGuid, Guid existingNodeGuid, int outPortIndex, int inPortIndex,
double x, double y, bool isDownstreamNode)
: base(new[] { newNodeGuid, existingNodeGuid })
{
OutputPortIndex = outPortIndex;
InputPortIndex = inPortIndex;
X = x;
Y = y;

IsDownstreamNode = isDownstreamNode;
}

#endregion

#region Public Command Properties

[DataMember]
internal int OutputPortIndex { get; private set; }

[DataMember]
internal int InputPortIndex { get; private set; }

[DataMember]
internal double X { get; private set; }

[DataMember]
internal double Y { get; private set; }

[DataMember]
internal bool IsDownstreamNode { get; private set; }

#endregion

#region Protected Overridable Methods

protected override void ExecuteCore(DynamoModel dynamoModel)
{
dynamoModel.PlaceAndConnectNodeImpl(this);
}

protected override void SerializeCore(XmlElement element)
{
base.SerializeCore(element);

var helper = new XmlElementHelper(element);
helper.SetAttribute("X", X);
helper.SetAttribute("Y", Y);
helper.SetAttribute("IsDownstreamNode", IsDownstreamNode);

helper.SetAttribute("OutPortIndex", OutputPortIndex);
helper.SetAttribute("InPortIndex", InputPortIndex);
}

#endregion

internal static PlaceAndConnectNodeCommand DeserializeCore(XmlElement element)
{
var helper = new XmlElementHelper(element);
double x = helper.ReadDouble("X");
double y = helper.ReadDouble("Y");
bool isDownstreamNode = helper.ReadBoolean("IsDownstreamNode");

var guids = DeserializeGuid(element, helper).ToList();
var newNodeGuid = guids.ElementAt(0);
var existingNodeGuid = guids.ElementAt(1);

int outPortIndex = helper.ReadInteger("OutPortIndex");
int inPortIndex = helper.ReadInteger("InPortIndex");

return new PlaceAndConnectNodeCommand(newNodeGuid, existingNodeGuid, outPortIndex, inPortIndex,
x, y, isDownstreamNode);
}

}

/// <summary>
/// A command containing additional information needed for creating a proxy custom node.
/// </summary>
Expand Down
2 changes: 2 additions & 0 deletions src/DynamoCoreWpf/Commands/DynamoCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ void OnModelCommandCompleted(DynamoModel.RecordableCommand command)
case "UngroupModelCommand":
case "AddModelToGroupCommand":
case "CreateAndConnectNodeCommand":
case "PlaceAndConnectNodeCommand":
RaiseCanExecuteUndoRedo();
break;

Expand Down Expand Up @@ -187,6 +188,7 @@ void OnModelCommandStarting(DynamoModel.RecordableCommand command)
case "AddPresetCommand":
case "ApplyPresetCommand":
case "CreateAndConnectNodeCommand":
case "PlaceAndConnectNodeCommand":
// for this commands there is no need
// to do anything before execution
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,12 +235,12 @@ public ImageSource LargeIcon
/// </summary>
public ICommand CreateAndConnectCommand { get; private set; }

public event Action<string, PortModel> CreateAndConnectToPort;
public event Action<NodeSearchElement, PortModel> CreateAndConnectToPort;
protected virtual void OnRequestCreateAndConnectToPort(PortModel portModel)
{
if (CreateAndConnectToPort != null)
{
CreateAndConnectToPort(Model.CreationName, portModel);
CreateAndConnectToPort(Model, portModel);
}
}

Expand Down
60 changes: 48 additions & 12 deletions src/DynamoCoreWpf/ViewModels/Search/SearchViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Windows;
using System.Windows.Media;
using Dynamo.Configuration;
using Dynamo.Controls;
using Dynamo.Graph.Nodes;
using Dynamo.Interfaces;
using Dynamo.Logging;
Expand Down Expand Up @@ -45,6 +46,8 @@ public void OnSearchTextChanged(object sender, EventArgs e)
#region Properties/Fields

private readonly IconServices iconServices;
private Tuple<NodeViewModel, PortModel> nodeAutoCompleteParams;
private bool onNodeViewReadyHandlerAttached;

/// <summary>
/// Position, where canvas was clicked.
Expand Down Expand Up @@ -346,6 +349,12 @@ public override void Dispose()
}
Model.EntryUpdated -= UpdateEntry;
Model.EntryRemoved -= RemoveEntry;

if (onNodeViewReadyHandlerAttached)
{
dynamoViewModel.NodeViewReady -= PlaceAndConnectNode;
onNodeViewReadyHandlerAttached = false;
}
base.Dispose();
}

Expand Down Expand Up @@ -1060,27 +1069,54 @@ public void OnSearchElementClicked(NodeModel nodeModel, Point position)
OnRequestFocusSearch();
}

internal void OnRequestConnectToPort(string nodeCreationName, PortModel portModel)
internal void OnRequestConnectToPort(NodeSearchElement nodeSearchElement, PortModel portModel)
{
// Do not auto connect code block node since default code block node do not have output port
if (!nodeCreationName.Contains("Code Block"))
if (!nodeSearchElement.CreationName.Contains("Code Block"))
{
//dynamoViewModel.ExecuteCommand(new DynamoModel.MakeConnectionCommand(nodeModel.GUID,))
var id = Guid.NewGuid();
// Create a new node based on node creation name and connect ports
var initialNode = dynamoViewModel.CurrentSpaceViewModel.Nodes.Where(x => x.Id == portModel.Owner.GUID).FirstOrDefault();
// Placing the new node based on which input port it is connecting to.
// The larger index for the input port, the lower the new node will be placed. 60 and 200 and offset we can adjust.
double adjustedY = initialNode.Y + (portModel.Index - 1) * 60 ;
// Placing the new node to the left of initial node
var adjustedX = initialNode.X - 200;
dynamoViewModel.ExecuteCommand(new DynamoModel.CreateAndConnectNodeCommand(id, portModel.Owner.GUID,
nodeCreationName, 0, portModel.Index, adjustedX, adjustedY, false, false));
var initialNode = dynamoViewModel.CurrentSpaceViewModel.Nodes.FirstOrDefault(x => x.Id == portModel.Owner.GUID);

var node = nodeSearchElement.CreateNode();
var createNodecmd = new DynamoModel.CreateNodeCommand(node, 0, 0, true, true);
dynamoViewModel.ExecuteCommand(createNodecmd);

nodeAutoCompleteParams = new Tuple<NodeViewModel, PortModel>(initialNode, portModel);

if (!onNodeViewReadyHandlerAttached)
{
dynamoViewModel.NodeViewReady += PlaceAndConnectNode;
onNodeViewReadyHandlerAttached = true;
}

}

OnRequestFocusSearch();
}

private void PlaceAndConnectNode(object sender, EventArgs e)
{
if (nodeAutoCompleteParams == null) return;

var nodeView = (NodeView)sender;
var node = nodeView.ViewModel.NodeModel;

var initialNode = nodeAutoCompleteParams.Item1;
var portModel = nodeAutoCompleteParams.Item2;

// Placing the new node based on which input port it is connecting to.
// The larger index for the input port, the lower the new node will be placed. 60 and 200 and offset we can adjust.
var adjustedY = initialNode.Y + (portModel.Index - 1) * node.Height;

// Placing the new node to the left of initial node
var adjustedX = initialNode.X - (initialNode.NodeModel.Width / 2 + node.Width / 2 + 50);

var id = node.GUID;

dynamoViewModel.ExecuteCommand(new DynamoModel.PlaceAndConnectNodeCommand(id, portModel.Owner.GUID,
0, portModel.Index, adjustedX, adjustedY, false));
}

#endregion

#region Commands
Expand Down