Adde full graph scrollbar
This commit is contained in:
parent
471ed3661c
commit
02047a4bd9
@ -67,16 +67,16 @@ namespace NanoBrain {
|
||||
Button addButton = new(() => OnAddClusterOutput()) {
|
||||
text = "Add"
|
||||
};
|
||||
outputContainer.Add(addButton);
|
||||
topMenuContainer?.Add(addButton);
|
||||
|
||||
Add(outputContainer);
|
||||
Add(topMenuContainer);
|
||||
}
|
||||
|
||||
void OnAddClusterOutput() {
|
||||
Nucleus newOutput = new Neuron(this.prefab, "New Output");
|
||||
this.prefab.RefreshOutputs();
|
||||
outputsField.choices = this.prefab.outputs.Select(output => output.name).ToList();
|
||||
outputsField.value = newOutput.name;
|
||||
outputsPopup.choices = this.prefab.outputs.Select(output => output.name).ToList();
|
||||
outputsPopup.value = newOutput.name;
|
||||
|
||||
this.currentNucleus = newOutput;
|
||||
}
|
||||
@ -88,7 +88,8 @@ namespace NanoBrain {
|
||||
this.serializedBrain = new SerializedObject(this.prefab);
|
||||
this.currentNucleus = nucleus;
|
||||
Rebuild(inspectorContainer);
|
||||
OnOutputChanged(outputsField.choices[0]);
|
||||
if (outputsPopup != null)
|
||||
OnOutputChanged(outputsPopup.choices[0]);
|
||||
}
|
||||
|
||||
void Rebuild(VisualElement inspectorContainer) {
|
||||
@ -173,7 +174,7 @@ namespace NanoBrain {
|
||||
if (newName != this.currentNucleus.name) {
|
||||
this.currentNucleus.name = newName;
|
||||
this.prefab.RefreshOutputs();
|
||||
outputsField.choices = this.prefab.outputs.Select(output => output.name).ToList();
|
||||
outputsPopup.choices = this.prefab.outputs.Select(output => output.name).ToList();
|
||||
anythingChanged = true;
|
||||
}
|
||||
}
|
||||
@ -492,10 +493,10 @@ namespace NanoBrain {
|
||||
}
|
||||
this.prefab.nuclei.Remove(nucleus);
|
||||
|
||||
if (outputsField.value == nucleus.name) {
|
||||
if (outputsPopup.value == nucleus.name) {
|
||||
this.prefab.RefreshOutputs();
|
||||
outputsField.choices = this.prefab.outputs.Select(output => output.name).ToList();
|
||||
outputsField.index = 0;
|
||||
outputsPopup.choices = this.prefab.outputs.Select(output => output.name).ToList();
|
||||
outputsPopup.index = 0;
|
||||
}
|
||||
|
||||
Neuron.Delete(nucleus);
|
||||
|
||||
@ -13,14 +13,18 @@ namespace NanoBrain {
|
||||
protected readonly ClusterPrefab prefab;
|
||||
protected SerializedObject serializedBrain;
|
||||
protected Nucleus currentNucleus;
|
||||
protected Nucleus selectedOutput;
|
||||
|
||||
protected GameObject gameObject;
|
||||
private List<NeuroidLayer> layers = new();
|
||||
private readonly Dictionary<Nucleus, Vector2Int> neuroidPositions = new();
|
||||
private bool expandArray = false;
|
||||
|
||||
protected ClusterPrefab prefabAsset;
|
||||
protected VisualElement outputContainer;
|
||||
protected readonly PopupField<string> outputsField;
|
||||
protected VisualElement topMenuContainer;
|
||||
protected ScrollView scrollView;
|
||||
protected IMGUIContainer graphContainer;
|
||||
protected readonly PopupField<string> outputsPopup;
|
||||
|
||||
public enum Mode {
|
||||
Focus,
|
||||
@ -34,37 +38,49 @@ namespace NanoBrain {
|
||||
name = "content";
|
||||
style.flexGrow = 1;
|
||||
|
||||
IMGUIContainer graphContainer = new(OnIMGUI);
|
||||
graphContainer.style.position = Position.Absolute;
|
||||
graphContainer.style.left = 0; graphContainer.style.top = 0;
|
||||
graphContainer.style.right = 0; graphContainer.style.bottom = 0;
|
||||
graphContainer.pickingMode = PickingMode.Position;
|
||||
graphContainer.focusable = true;
|
||||
Add(graphContainer);
|
||||
|
||||
outputContainer = new() {
|
||||
topMenuContainer = new() {
|
||||
style = {
|
||||
flexDirection = FlexDirection.Row,
|
||||
alignItems = Align.Center,
|
||||
}
|
||||
};
|
||||
|
||||
EnumField enumField = new(mode);
|
||||
enumField.style.width = 80;
|
||||
enumField.RegisterValueChangedCallback(OnModeChange);
|
||||
outputContainer.Add(enumField);
|
||||
|
||||
EnumField modePopup = new(mode);
|
||||
modePopup.style.width = 80;
|
||||
modePopup.RegisterValueChangedCallback(OnModeChange);
|
||||
topMenuContainer.Add(modePopup);
|
||||
|
||||
List<string> names = this.prefab.outputs.Select(output => output.name).ToList();
|
||||
if (names.Count > 0 && names.First() != null) {
|
||||
outputsField = new(names, names.First()) {
|
||||
outputsPopup = new(names, names.First()) {
|
||||
style = { flexGrow = 1 }
|
||||
};
|
||||
outputsField.RegisterValueChangedCallback(evt => OnOutputChanged(evt.newValue));
|
||||
outputContainer.Add(outputsField);
|
||||
outputsPopup.RegisterValueChangedCallback(evt => OnOutputChanged(evt.newValue));
|
||||
topMenuContainer.Add(outputsPopup);
|
||||
}
|
||||
Add(topMenuContainer);
|
||||
|
||||
scrollView = new(ScrollViewMode.Horizontal);
|
||||
scrollView.style.position = Position.Absolute;
|
||||
scrollView.style.left = 0; scrollView.style.top = 0;
|
||||
scrollView.style.right = 0; scrollView.style.bottom = 0;
|
||||
//scrollView.style.flexGrow = 1;
|
||||
scrollView.horizontalScrollerVisibility = ScrollerVisibility.Auto; // Auto shows when needed
|
||||
scrollView.verticalScrollerVisibility = ScrollerVisibility.Hidden;
|
||||
|
||||
graphContainer = new(OnIMGUI);
|
||||
//graphContainer.style.position = Position.Relative; // or omit this line
|
||||
//graphContainer.style.position = Position.Absolute;
|
||||
// graphContainer.style.left = 0; graphContainer.style.top = 0;
|
||||
// graphContainer.style.right = 0; graphContainer.style.bottom = 0;
|
||||
graphContainer.pickingMode = PickingMode.Position;
|
||||
graphContainer.focusable = true;
|
||||
//graphContainer.style.width = 1200;
|
||||
//graphContainer.style.width = new StyleLength(StyleKeyword.Null); // allow content to determine width
|
||||
|
||||
scrollView.contentContainer.Add(graphContainer);
|
||||
Add(scrollView);
|
||||
|
||||
Add(outputContainer);
|
||||
|
||||
// Subscribe when added to panel (editor UI ready)
|
||||
RegisterCallback<AttachToPanelEvent>(evt => Subscribe());
|
||||
@ -75,7 +91,6 @@ namespace NanoBrain {
|
||||
mode = (Mode)evt.newValue;
|
||||
}
|
||||
|
||||
protected Nucleus selectedOutput;
|
||||
protected virtual void OnOutputChanged(string outputName) {
|
||||
if (this.currentNucleus.parent != null)
|
||||
// Get nucleus in the parent instance
|
||||
@ -86,6 +101,7 @@ namespace NanoBrain {
|
||||
this.currentNucleus = this.selectedOutput;
|
||||
}
|
||||
|
||||
|
||||
bool subscribed = false;
|
||||
void Subscribe() {
|
||||
if (subscribed) return;
|
||||
@ -106,8 +122,8 @@ namespace NanoBrain {
|
||||
this.serializedBrain = new SerializedObject(this.prefab);
|
||||
this.currentNucleus = nucleus;
|
||||
Rebuild(); //inspectorContainer);
|
||||
OnOutputChanged(outputsField.choices[0]);
|
||||
|
||||
if (outputsPopup != null)
|
||||
OnOutputChanged(outputsPopup.choices[0]);
|
||||
}
|
||||
|
||||
void Rebuild() {
|
||||
@ -190,9 +206,10 @@ namespace NanoBrain {
|
||||
Handles.BeginGUI();
|
||||
DrawGraph();
|
||||
Handles.EndGUI();
|
||||
|
||||
}
|
||||
|
||||
#region Graph
|
||||
|
||||
protected virtual void DrawGraph() {
|
||||
if (mode == Mode.Focus)
|
||||
DrawFocusGraph();
|
||||
@ -200,6 +217,8 @@ namespace NanoBrain {
|
||||
DrawFullGraph();
|
||||
}
|
||||
|
||||
#region Full Graph
|
||||
|
||||
protected void DrawFullGraph() {
|
||||
//Dag dag = GenerateGraph(this.prefab);
|
||||
Dag dag = GenerateGraph(this.selectedOutput);
|
||||
@ -219,6 +238,31 @@ namespace NanoBrain {
|
||||
// Draw nodes
|
||||
foreach (DagNode n in dag.nodes)
|
||||
DrawNucleus(n.nucleus, n.position, 1, n.radius);
|
||||
|
||||
// Determine graph width
|
||||
float width = 0;
|
||||
float currentNucleusPosition = 0;
|
||||
foreach (DagNode node in dag.nodes) {
|
||||
if (node.position.x > width)
|
||||
width = node.position.x;
|
||||
if (node.nucleus == currentNucleus)
|
||||
currentNucleusPosition = node.position.x;
|
||||
}
|
||||
|
||||
// Resize the graph container to the full graph width
|
||||
float margin = 50f;
|
||||
graphContainer.style.width = width + 2 * margin;
|
||||
|
||||
// Scroll to the current nucleus
|
||||
float viewportWidth = scrollView.layout.width;
|
||||
// center currentNucleus in viewport
|
||||
float desiredScrollX = currentNucleusPosition - viewportWidth * 0.5f;
|
||||
// clamp between 0 and maximum scrollable range
|
||||
float maxScrollX = Mathf.Max(0f, graphContainer.resolvedStyle.width - viewportWidth);
|
||||
desiredScrollX = Mathf.Clamp(desiredScrollX, 0f, maxScrollX);
|
||||
|
||||
Vector2 current = scrollView.scrollOffset;
|
||||
scrollView.scrollOffset = new Vector2(desiredScrollX, current.y);
|
||||
}
|
||||
|
||||
public Dag GenerateGraph(Nucleus rootNucleus) {
|
||||
@ -258,6 +302,10 @@ namespace NanoBrain {
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Full Graph
|
||||
|
||||
#region Focus Graph
|
||||
|
||||
protected void DrawFocusGraph() {
|
||||
float size = 20;
|
||||
Vector3 position = new(150, 210, 0);
|
||||
@ -334,6 +382,7 @@ namespace NanoBrain {
|
||||
maxValue = cluster.defaultOutput.outputMagnitude;
|
||||
DrawNucleus(this.currentNucleus, position, maxValue, 20);
|
||||
}
|
||||
graphContainer.style.width = 300;
|
||||
}
|
||||
|
||||
private void DrawReceivers(Nucleus nucleus, Vector3 parentPos, float size) {
|
||||
@ -455,6 +504,8 @@ namespace NanoBrain {
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Focus Graph
|
||||
|
||||
protected void DrawNucleus(Nucleus nucleus, Vector3 position, float maxValue, float size) {
|
||||
Color color;
|
||||
if (Application.isPlaying) {
|
||||
@ -647,19 +698,7 @@ namespace NanoBrain {
|
||||
Handles.DrawLine(from, to);
|
||||
}
|
||||
|
||||
// protected void DrawNode(Vector2 position, float size) {
|
||||
// Handles.color = Color.black * 0.9f;
|
||||
// Handles.DrawSolidDisc(position, Vector3.forward, size);
|
||||
|
||||
// Handles.color = Color.white;
|
||||
// GUIStyle style = new(EditorStyles.label) {
|
||||
// alignment = TextAnchor.UpperCenter,
|
||||
// normal = { textColor = Color.white },
|
||||
// fontStyle = FontStyle.Bold,
|
||||
// };
|
||||
// Vector3 labelPos = position - Vector3.down * (size + 10f); // below disc along up axis
|
||||
// Handles.Label(labelPos, n.title, style);
|
||||
// }
|
||||
#endregion Graph
|
||||
|
||||
void OnSceneGUI(SceneView sceneView) {
|
||||
if (this.gameObject != null) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user