1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Script editor - Added auto-arrange button

This commit is contained in:
Robert 2022-09-24 12:13:12 +02:00
parent 3ecf0bed5a
commit 65b8b377ec
5 changed files with 89 additions and 7 deletions

View File

@ -93,6 +93,7 @@
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=stores_005Cregistrations/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=utilities/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=visualscripting/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=visualscripting_005Cextensions/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=visualscripting_005Cinterfaces/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=visualscripting_005Cnodes/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=visualscripting_005Cpins/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@ -19,7 +19,7 @@ public static class NodeScriptExtension
levels[currentLevelNode] = 0; // DarthAffe 13.09.2022: Init-exit nodes as zero
int currentLevel = 1;
while (currentLevelNodes.Count > 0)
while (currentLevelNodes.Count > 0 && currentLevel < 1000)
{
List<INode> nextLevelNodes = currentLevelNodes.SelectMany(node => node.Pins
.Where(x => x.Direction == PinDirection.Input)

View File

@ -0,0 +1,43 @@
using System.Collections.Generic;
using System.Linq;
using Artemis.Core;
namespace Artemis.UI.Shared.Services.NodeEditor.Commands;
/// <summary>
/// Represents a node editor command that can be used to organize a script
/// </summary>
public class OrganizeScript : INodeEditorCommand
{
private readonly NodeScript _script;
private readonly List<(INode node, double x, double y)> _originalPositions;
/// <summary>
/// Creates a new instance of the <see cref="OrganizeScript"/> class.
/// </summary>
/// <param name="script">The script to organize.</param>
public OrganizeScript(NodeScript script)
{
_script = script;
_originalPositions = script.Nodes.Select(n => (n, n.X, n.Y)).ToList();
}
/// <inheritdoc />
public string DisplayName => "Organize script";
/// <inheritdoc />
public void Execute()
{
_script.Organize();
}
/// <inheritdoc />
public void Undo()
{
foreach ((INode? node, double x, double y) in _originalPositions)
{
node.X = x;
node.Y = y;
}
}
}

View File

@ -43,6 +43,11 @@
</DataTemplate>
</MenuItem.DataTemplates>
</MenuItem>
<MenuItem Header="Auto-arrange" Command="{CompiledBinding AutoArrange}">
<MenuItem.Icon>
<avalonia:MaterialIcon Kind="Sort" />
</MenuItem.Icon>
</MenuItem>
<Separator />
<MenuItem Header="Export Script" Command="{CompiledBinding Export}">
<MenuItem.Icon>

View File

@ -26,6 +26,7 @@ public class NodeScriptWindowViewModel : NodeScriptWindowViewModelBase
private readonly IProfileService _profileService;
private readonly ISettingsService _settingsService;
private readonly IWindowService _windowService;
private bool _pauseUpdate;
public NodeScriptWindowViewModel(NodeScript nodeScript,
INodeService nodeService,
@ -56,6 +57,7 @@ public class NodeScriptWindowViewModel : NodeScriptWindowViewModelBase
Categories = categories;
CreateNode = ReactiveCommand.Create<NodeData>(ExecuteCreateNode);
AutoArrange = ReactiveCommand.CreateFromTask(ExecuteAutoArrange);
Export = ReactiveCommand.CreateFromTask(ExecuteExport);
Import = ReactiveCommand.CreateFromTask(ExecuteImport);
@ -83,6 +85,7 @@ public class NodeScriptWindowViewModel : NodeScriptWindowViewModelBase
public ReactiveCommand<string, Unit> OpenUri { get; set; }
public ReadOnlyObservableCollection<IGrouping<NodeData, string>> Categories { get; }
public ReactiveCommand<NodeData, Unit> CreateNode { get; }
public ReactiveCommand<Unit, Unit> AutoArrange { get; }
public ReactiveCommand<Unit, Unit> Export { get; }
public ReactiveCommand<Unit, Unit> Import { get; }
@ -108,6 +111,27 @@ public class NodeScriptWindowViewModel : NodeScriptWindowViewModelBase
_nodeEditorService.ExecuteCommand(NodeScript, new AddNode(NodeScript, node));
}
private async Task ExecuteAutoArrange()
{
try
{
if (!NodeScript.ExitNodeConnected)
{
await _windowService.ShowConfirmContentDialog("Cannot auto-arrange", "The exit node must be connected in order to perform auto-arrange.", "Close", null);
return;
}
_pauseUpdate = true;
_nodeEditorService.ExecuteCommand(NodeScript, new OrganizeScript(NodeScript));
await Task.Delay(200);
NodeScriptViewModel.RequestAutoFit();
}
finally
{
_pauseUpdate = false;
}
}
private async Task ExecuteExport()
{
// Might not cover everything but then the dialog will complain and that's good enough
@ -131,17 +155,26 @@ public class NodeScriptWindowViewModel : NodeScriptWindowViewModelBase
if (result == null)
return;
string json = await File.ReadAllTextAsync(result[0]);
_nodeService.ImportScript(json, NodeScript);
History.Clear();
try
{
_pauseUpdate = true;
string json = await File.ReadAllTextAsync(result[0]);
_nodeService.ImportScript(json, NodeScript);
History.Clear();
await Task.Delay(200);
NodeScriptViewModel.RequestAutoFit();
await Task.Delay(200);
NodeScriptViewModel.RequestAutoFit();
}
finally
{
_pauseUpdate = false;
}
}
private void Update(object? sender, EventArgs e)
{
NodeScript.Run();
if (!_pauseUpdate)
NodeScript.Run();
}
private void Save(object? sender, EventArgs e)