mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Added extension to organize node-graphs
This commit is contained in:
parent
6ed349d4c8
commit
1c6e7bde46
@ -93,4 +93,5 @@
|
||||
<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></wpf:ResourceDictionary>
|
||||
26
src/Artemis.Core/VisualScripting/Extensions/NodeExtension.cs
Normal file
26
src/Artemis.Core/VisualScripting/Extensions/NodeExtension.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Artemis.Core;
|
||||
|
||||
public static class NodeExtension
|
||||
{
|
||||
#region Methods
|
||||
|
||||
public static double EstimateHeight(this INode node)
|
||||
{
|
||||
const double PIN_HEIGHT = 26;
|
||||
const double TITLE_HEIGHT = 46;
|
||||
|
||||
int inputPinCount = node.Pins.Count(x => x.Direction == PinDirection.Input)
|
||||
+ node.PinCollections.Where(x => x.Direction == PinDirection.Input).Sum(x => x.Count() + 1);
|
||||
int outputPinCount = node.Pins.Count(x => x.Direction == PinDirection.Output)
|
||||
+ node.PinCollections.Where(x => x.Direction == PinDirection.Output).Sum(x => x.Count() + 1);
|
||||
|
||||
return TITLE_HEIGHT + (Math.Max(inputPinCount, outputPinCount) * PIN_HEIGHT);
|
||||
}
|
||||
|
||||
public static double EstimateWidth(this INode node) => 120; // DarthAffe 13.09.2022: For now just assume they are all the same size
|
||||
|
||||
#endregion
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Artemis.Core;
|
||||
|
||||
public static class NodeScriptExtension
|
||||
{
|
||||
#region Methods
|
||||
|
||||
public static void Organize(this NodeScript nodeScript)
|
||||
{
|
||||
const double SPACING_HORIZONTAL = 160;
|
||||
const double SPACING_VERTICAL = 20;
|
||||
|
||||
Dictionary<INode, int> levels = nodeScript.Nodes.ToDictionary(node => node, _ => -1);
|
||||
|
||||
List<INode> currentLevelNodes = nodeScript.Nodes.Where(x => x.IsExitNode).ToList();
|
||||
foreach (INode currentLevelNode in currentLevelNodes)
|
||||
levels[currentLevelNode] = 0; // DarthAffe 13.09.2022: Init-exit nodes as zero
|
||||
|
||||
int currentLevel = 1;
|
||||
while (currentLevelNodes.Count > 0)
|
||||
{
|
||||
List<INode> nextLevelNodes = currentLevelNodes.SelectMany(node => node.Pins
|
||||
.Where(x => x.Direction == PinDirection.Input)
|
||||
.SelectMany(x => x.ConnectedTo)
|
||||
.Select(x => x.Node)
|
||||
.Concat(node.PinCollections
|
||||
.Where(x => x.Direction == PinDirection.Input)
|
||||
.SelectMany(x => x)
|
||||
.SelectMany(x => x.ConnectedTo)
|
||||
.Select(x => x.Node)))
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
foreach (INode nextLevelNode in nextLevelNodes)
|
||||
if (currentLevel > levels[nextLevelNode])
|
||||
levels[nextLevelNode] = currentLevel;
|
||||
|
||||
currentLevelNodes = nextLevelNodes;
|
||||
currentLevel++;
|
||||
}
|
||||
|
||||
void LayoutLevel(IList<INode> nodes, double posX, double posY)
|
||||
{
|
||||
foreach (INode node in nodes)
|
||||
{
|
||||
node.X = posX;
|
||||
node.Y = posY;
|
||||
|
||||
posY += SPACING_VERTICAL + node.EstimateHeight();
|
||||
}
|
||||
}
|
||||
|
||||
List<INode>? unusedNodes = null;
|
||||
double unusedPosY = 0;
|
||||
double level0Width = 0;
|
||||
|
||||
double positionX = 0;
|
||||
foreach (IGrouping<int, INode> levelGroup in levels.GroupBy(x => x.Value, x => x.Key).OrderBy(x => x.Key))
|
||||
{
|
||||
List<INode> nodes = levelGroup.ToList();
|
||||
double levelHeight = nodes.Sum(x => x.EstimateHeight()) + ((nodes.Count - 1) * SPACING_VERTICAL);
|
||||
double levelWidth = nodes.Max(x => x.EstimateWidth());
|
||||
double positionY = -(levelHeight / 2.0);
|
||||
|
||||
if (levelGroup.Key == -1)
|
||||
{
|
||||
unusedNodes = nodes;
|
||||
unusedPosY = positionY;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (levelGroup.Key == 0)
|
||||
level0Width = levelWidth;
|
||||
|
||||
LayoutLevel(nodes, positionX, positionY);
|
||||
|
||||
positionX -= SPACING_HORIZONTAL + levelWidth;
|
||||
}
|
||||
}
|
||||
|
||||
if (unusedNodes != null)
|
||||
LayoutLevel(unusedNodes, level0Width + (SPACING_HORIZONTAL / 2.0), unusedPosY);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user