Skip to content

Commit

Permalink
Rewrite editor navigation model
Browse files Browse the repository at this point in the history
  - Add workflow explorer treeview
  - Allow navigating to any level without opening previous levels
  - Allow visualizers to run uncoupled from the workflow view
  - Highlight build errors in explorer treeview
  • Loading branch information
glopesdev committed Jul 2, 2024
1 parent aa8afae commit 8a52603
Show file tree
Hide file tree
Showing 20 changed files with 839 additions and 1,192 deletions.
1 change: 1 addition & 0 deletions Bonsai.Editor.Tests/MockGraphView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public MockGraphView(ExpressionBuilderGraph workflow = null)
Workflow = workflow ?? new ExpressionBuilderGraph();
CommandExecutor = new CommandExecutor();
var serviceContainer = new ServiceContainer();
serviceContainer.AddService(typeof(WorkflowBuilder), new WorkflowBuilder(Workflow));
serviceContainer.AddService(typeof(CommandExecutor), CommandExecutor);
ServiceProvider = serviceContainer;
}
Expand Down
1 change: 0 additions & 1 deletion Bonsai.Editor.Tests/WorkflowEditorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ static string ToString(IEnumerable<T> sequence)
var editor = new WorkflowEditor(graphView.ServiceProvider, graphView);
editor.UpdateLayout.Subscribe(graphView.UpdateGraphLayout);
editor.UpdateSelection.Subscribe(graphView.UpdateSelection);
editor.Workflow = graphView.Workflow;

var nodeSequence = editor.GetGraphValues().ToArray();
return (editor, assertIsReversible: () =>
Expand Down
126 changes: 100 additions & 26 deletions Bonsai.Editor/EditorForm.Designer.cs

Large diffs are not rendered by default.

270 changes: 132 additions & 138 deletions Bonsai.Editor/EditorForm.cs

Large diffs are not rendered by default.

41 changes: 0 additions & 41 deletions Bonsai.Editor/GraphModel/WorkflowBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,47 +91,6 @@ public static IEnumerable<ContextGrouping> GetDependentExpressions(this SubjectD
}
}
}

public static ExpressionScope GetExpressionScope(this WorkflowBuilder source, ExpressionBuilder target)
{
return GetExpressionScope(source.Workflow, target);
}

static ExpressionScope GetExpressionScope(ExpressionBuilderGraph source, ExpressionBuilder target)
{
foreach (var node in source)
{
var builder = ExpressionBuilder.Unwrap(node.Value);
if (builder == target)
{
return new ExpressionScope(node.Value, innerScope: null);
}

if (builder is IWorkflowExpressionBuilder workflowBuilder)
{
var innerScope = GetExpressionScope(workflowBuilder.Workflow, target);
if (innerScope != null)
{
return new ExpressionScope(node.Value, innerScope);
}
}
}

return null;
}
}

class ExpressionScope
{
public ExpressionScope(ExpressionBuilder value, ExpressionScope innerScope)
{
Value = value;
InnerScope = innerScope;
}

public ExpressionBuilder Value { get; }

public ExpressionScope InnerScope { get; }
}

class SubjectDefinition
Expand Down
58 changes: 49 additions & 9 deletions Bonsai.Editor/GraphModel/WorkflowEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ class WorkflowEditor
readonly IGraphView graphView;
readonly Subject<Exception> error;
readonly Subject<bool> updateLayout;
readonly Subject<bool> updateParentLayout;
readonly Subject<bool> invalidateLayout;
readonly Subject<IEnumerable<ExpressionBuilder>> updateSelection;
readonly Subject<IWorkflowExpressionBuilder> closeWorkflowEditor;
WorkflowEditorPath workflowPath;

public WorkflowEditor(IServiceProvider provider, IGraphView view)
{
Expand All @@ -32,20 +32,47 @@ public WorkflowEditor(IServiceProvider provider, IGraphView view)
commandExecutor = (CommandExecutor)provider.GetService(typeof(CommandExecutor));
error = new Subject<Exception>();
updateLayout = new Subject<bool>();
updateParentLayout = new Subject<bool>();
invalidateLayout = new Subject<bool>();
updateSelection = new Subject<IEnumerable<ExpressionBuilder>>();
closeWorkflowEditor = new Subject<IWorkflowExpressionBuilder>();
WorkflowPath = null;
}

public ExpressionBuilderGraph Workflow { get; set; }
public ExpressionBuilderGraph Workflow { get; private set; }

public bool IsReadOnly { get; private set; }

public WorkflowEditorPath WorkflowPath
{
get { return workflowPath; }
set
{
workflowPath = value;
var workflowBuilder = (WorkflowBuilder)serviceProvider.GetService(typeof(WorkflowBuilder));
if (workflowPath != null)
{
var builder = ExpressionBuilder.Unwrap(workflowPath.Resolve(workflowBuilder, out bool isReadOnly));
if (builder is not IWorkflowExpressionBuilder workflowExpressionBuilder)
{
throw new ArgumentException(Resources.InvalidWorkflowPath_Error, nameof(value));
}

Workflow = workflowExpressionBuilder.Workflow;
IsReadOnly = isReadOnly;
}
else
{
Workflow = workflowBuilder.Workflow;
IsReadOnly = false;
}
updateLayout.OnNext(false);
}
}

public IObservable<Exception> Error => error;

public IObservable<bool> UpdateLayout => updateLayout;

public IObservable<bool> UpdateParentLayout => updateParentLayout;

public IObservable<bool> InvalidateLayout => invalidateLayout;

public IObservable<IEnumerable<ExpressionBuilder>> UpdateSelection => updateSelection;
Expand Down Expand Up @@ -170,8 +197,6 @@ private void AddWorkflowInput(ExpressionBuilderGraph workflow, Node<ExpressionBu
inputBuilder.Index++;
}
}

updateParentLayout.OnNext(false);
}
}

Expand All @@ -187,8 +212,6 @@ private void RemoveWorkflowInput(ExpressionBuilderGraph workflow, Node<Expressio
inputBuilder.Index--;
}
}

updateParentLayout.OnNext(false);
}
}

Expand Down Expand Up @@ -2069,6 +2092,23 @@ public GraphNode FindGraphNode(ExpressionBuilder value)
{
return graphView.Nodes.SelectMany(layer => layer).FirstOrDefault(n => n.Value == value);
}

public void NavigateTo(WorkflowEditorPath path)
{
if (path == workflowPath)
return;

var previousPath = workflowPath;
var selectedNodes = graphView.SelectedNodes.ToArray();
var restoreSelectedNodes = CreateUpdateSelectionDelegate(selectedNodes);
commandExecutor.Execute(
() => WorkflowPath = path,
() =>
{
WorkflowPath = previousPath;
restoreSelectedNodes();
});
}
}

enum CreateGraphNodeType
Expand Down
Loading

0 comments on commit 8a52603

Please sign in to comment.