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

Add support for context-dependent renaming of subjects #921

Merged
merged 7 commits into from
Aug 8, 2022
Merged
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
27 changes: 25 additions & 2 deletions Bonsai.Editor/EditorForm.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

152 changes: 146 additions & 6 deletions Bonsai.Editor/EditorForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ IObservable<Unit> InitializeSubjectSources()
var isEmpty = subjectCategory.Nodes.Count == 0;
subjectCategory.Nodes.Clear();

var nameProperty = TypeDescriptor.GetProperties(typeof(SubscribeSubjectBuilder))["Name"];
var nameProperty = TypeDescriptor.GetProperties(typeof(SubscribeSubjectBuilder))[nameof(SubscribeSubjectBuilder.Name)];
var subjects = nameProperty.Converter.GetStandardValues(new TypeDescriptorContext(workflowBuilder, nameProperty, editorSite));
if (subjects != null && subjects.Count > 0)
{
Expand Down Expand Up @@ -1452,6 +1452,36 @@ void HandleWorkflowCompleted()
else clearErrors();
}

void HighlightDeclaration(WorkflowGraphView workflowView, ExpressionDeclaration declaration)
{
if (workflowView == null)
{
throw new ArgumentNullException(nameof(workflowView));
}

var graphNode = workflowView.FindGraphNode(declaration.Value);
if (graphNode != null)
{
workflowView.GraphView.SelectedNode = graphNode;
var nestedDeclaration = declaration.InnerDeclaration;
if (nestedDeclaration != null)
{
workflowView.LaunchWorkflowView(graphNode);
var editorLauncher = workflowView.GetWorkflowEditorLauncher(graphNode);
if (editorLauncher != null)
{
HighlightDeclaration(editorLauncher.WorkflowGraphView, nestedDeclaration);
}
}
else
{
var ownerForm = workflowView.EditorControl.ParentForm;
if (ownerForm != null) ownerForm.Activate();
workflowView.SelectGraphNode(graphNode);
}
}
}

#endregion

#region Workflow Controller
Expand Down Expand Up @@ -1767,6 +1797,9 @@ private void searchTextBox_KeyDown(object sender, KeyEventArgs e)
toolboxTreeView.SelectedNode = toolboxTreeView.SelectedNode.NextVisibleNode ?? toolboxTreeView.SelectedNode;
e.Handled = true;
break;
case Keys.F2:
toolboxTreeView_KeyDown(sender, e);
break;
case Keys.Return:
toolboxTreeView_KeyDown(sender, e);
searchTextBox.Clear();
Expand Down Expand Up @@ -1846,17 +1879,80 @@ void UpdateTreeViewSelection(bool focused)
selectedNode.BackColor = focused ? Color.Empty : themeRenderer.ToolStripRenderer.ColorTable.InactiveCaption;
}

void SelectTreeViewSubjectNode(string subjectName)
{
var subjectCategory = toolboxCategories[SubjectCategoryName];
var subjectNode = subjectCategory.Nodes.Find(subjectName, false);
if (subjectNode.Length > 0)
{
toolboxTreeView.SelectedNode = subjectNode[0];
}
}

private void toolboxTreeView_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Return &&
toolboxTreeView.SelectedNode != null &&
toolboxTreeView.SelectedNode.Tag != null)
var selectedNode = toolboxTreeView.SelectedNode;
if (e.KeyCode == Keys.Return && selectedNode?.Tag != null)
{
var typeNode = toolboxTreeView.SelectedNode;
CreateGraphNode(typeNode, e.Modifiers);
CreateGraphNode(selectedNode, e.Modifiers);
e.Handled = true;
e.SuppressKeyPress = true;
}

var rename = e.KeyCode == Keys.F2;
var goToDefinition = e.KeyCode == Keys.F12;
if ((rename || goToDefinition) && selectedNode?.Tag != null)
{
var elementCategory = WorkflowGraphView.GetToolboxElementCategory(selectedNode);
if (!selectedNode.IsEditing && elementCategory == ~ElementCategory.Source)
{
var currentName = selectedNode.Name;
var selectedView = selectionModel.SelectedView;
var definition = workflowBuilder.GetSubjectDefinition(selectedView.Workflow, currentName);
if (definition == null || rename && definition.IsReadOnly)
{
var message = definition == null
? Resources.SubjectDefinitionNotFound_Error
: string.Format(Resources.RenameReadOnlySubjectDefinition_Error, currentName);
editorSite.ShowError(message);
return;
}

if (rename)
{
toolboxTreeView.LabelEdit = true;
selectedNode.BeginEdit();
}
else
{
var declaration = workflowBuilder.GetDeclaration(definition.Subject);
HighlightDeclaration(editorControl.WorkflowGraphView, declaration);
}
}
}
}

private void toolboxTreeView_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
{
e.CancelEdit = true;

var selectedView = selectionModel.SelectedView;
if (e.Node == null || string.IsNullOrEmpty(e.Label) || selectedView == null)
{
return;
}

var newName = e.Label;
var currentName = e.Node.Name;
var currentLabel = e.Node.Text;
var definition = workflowBuilder.GetSubjectDefinition(selectedView.Workflow, currentName);
selectedView.Editor.RenameSubject(definition, newName);
e.Node.Name = newName;
e.Node.Text = newName + currentLabel.Substring(currentName.Length);
toolboxTreeView.LabelEdit = false;
searchTextBox.Clear();
SelectTreeViewSubjectNode(newName);
UpdatePropertyGrid();
}

private void toolboxTreeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
Expand Down Expand Up @@ -1893,6 +1989,8 @@ private void toolboxTreeView_MouseUp(object sender, MouseEventArgs e)
}
subscribeSubjectToolStripMenuItem.Visible = true;
multicastSubjectToolStripMenuItem.Visible = true;
renameSubjectToolStripMenuItem.Visible = true;
goToDefinitionToolStripMenuItem.Visible = true;
}
else
{
Expand All @@ -1908,6 +2006,8 @@ private void toolboxTreeView_MouseUp(object sender, MouseEventArgs e)
createGroupToolStripMenuItem.Visible = allowGroup || selectionType != null;
subscribeSubjectToolStripMenuItem.Visible = false;
multicastSubjectToolStripMenuItem.Visible = false;
renameSubjectToolStripMenuItem.Visible = false;
goToDefinitionToolStripMenuItem.Visible = false;
insertBeforeToolStripMenuItem.Visible = true;
}
toolboxContextMenuStrip.Show(toolboxTreeView, e.X, e.Y);
Expand Down Expand Up @@ -1946,6 +2046,32 @@ private void createGroupToolStripMenuItem_Click(object sender, EventArgs e)
toolboxTreeView_KeyDown(sender, new KeyEventArgs(Keys.Control | Keys.Return));
}

private void renameSubjectToolStripMenuItem_Click(object sender, EventArgs e)
{
if (!toolboxTreeView.Focused)
{
var model = selectionModel.SelectedView;
if (!model.GraphView.Focused) return;

var selection = selectionModel.SelectedNodes.ToArray();
var selectedBuilder = selection?.Length == 1 && selection?[0].Value is InspectBuilder inspectBuilder ? inspectBuilder.Builder : null;
if (selectedBuilder is SubjectExpressionBuilder ||
selectedBuilder is SubscribeSubjectBuilder ||
selectedBuilder is MulticastSubjectBuilder)
{
var subjectName = ((INamedElement)selectedBuilder).Name;
SelectTreeViewSubjectNode(subjectName);
}
}

toolboxTreeView_KeyDown(sender, new KeyEventArgs(Keys.F2));
}

private void goToDefinitionToolStripMenuItem_Click(object sender, EventArgs e)
{
toolboxTreeView_KeyDown(sender, new KeyEventArgs(Keys.F12));
}

private void MainForm_KeyDown(object sender, KeyEventArgs e)
{
editorSite.OnKeyDown(e);
Expand Down Expand Up @@ -2290,6 +2416,7 @@ public void OnKeyDown(KeyEventArgs e)
HandleMenuItemShortcutKeys(e, siteForm.startToolStripButtonMenuItem, siteForm.startToolStripMenuItem_Click);
HandleMenuItemShortcutKeys(e, siteForm.restartToolStripMenuItem, siteForm.restartToolStripMenuItem_Click);
HandleMenuItemShortcutKeys(e, siteForm.stopToolStripMenuItem, siteForm.stopToolStripMenuItem_Click);
HandleMenuItemShortcutKeys(e, siteForm.renameSubjectToolStripMenuItem, siteForm.renameSubjectToolStripMenuItem_Click);
}

public void OnKeyPress(KeyPressEventArgs e)
Expand Down Expand Up @@ -2443,6 +2570,19 @@ public bool HasDefinition(object component)

public void ShowDefinition(object component)
{
if (component is INamedElement namedElement &&
(namedElement is SubscribeSubjectBuilder || namedElement is MulticastSubjectBuilder))
{
var model = siteForm.selectionModel.SelectedView ?? siteForm.editorControl.WorkflowGraphView;
var definition = siteForm.workflowBuilder.GetSubjectDefinition(model.Workflow, namedElement.Name);
if (definition != null)
{
var declaration = siteForm.workflowBuilder.GetDeclaration(definition.Subject);
siteForm.HighlightDeclaration(siteForm.editorControl.WorkflowGraphView, declaration);
return;
}
}

Type componentType;
if (siteForm.scriptEnvironment == null) return;
if (siteForm.scriptEnvironment.AssemblyName != null &&
Expand Down
Loading