diff --git a/Examples/Nodes.meta b/Examples/Nodes.meta new file mode 100644 index 0000000..0d29f0a --- /dev/null +++ b/Examples/Nodes.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 31c1681f5df4f764ab4ca7f09cd3be7d +folderAsset: yes +timeCreated: 1505462700 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Examples/Nodes/BaseNode.cs b/Examples/Nodes/BaseNode.cs new file mode 100644 index 0000000..1a7bbd4 --- /dev/null +++ b/Examples/Nodes/BaseNode.cs @@ -0,0 +1,16 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class BaseNode : Node { + + // Use this for initialization + void Start () { + + } + + // Update is called once per frame + void Update () { + + } +} diff --git a/Examples/Nodes/BaseNode.cs.meta b/Examples/Nodes/BaseNode.cs.meta new file mode 100644 index 0000000..e525d86 --- /dev/null +++ b/Examples/Nodes/BaseNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 23665941e8cd89a48b1272ac5fd6510c +timeCreated: 1505462705 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Editor/NodeEditor.cs b/Scripts/Editor/NodeEditor.cs new file mode 100644 index 0000000..1030457 --- /dev/null +++ b/Scripts/Editor/NodeEditor.cs @@ -0,0 +1,12 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; + +public class NodeEditor : Editor { + + + public override void OnInspectorGUI() { + base.OnInspectorGUI(); + } +} diff --git a/Scripts/Editor/NodeEditor.cs.meta b/Scripts/Editor/NodeEditor.cs.meta new file mode 100644 index 0000000..db8651d --- /dev/null +++ b/Scripts/Editor/NodeEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 712c3fc5d9eeb4c45b1e23918df6018f +timeCreated: 1505462176 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Editor/NodeEditorAction.cs b/Scripts/Editor/NodeEditorAction.cs index 3563594..1c4aac0 100644 --- a/Scripts/Editor/NodeEditorAction.cs +++ b/Scripts/Editor/NodeEditorAction.cs @@ -2,26 +2,53 @@ using System.Collections.Generic; using UnityEngine; using UnityEditor; +using System; +using UNEC; public static class NodeEditorAction { - public static void Controls(NodeEditorWindow window) { + public static NodeEditorWindow window { get { return NodeEditorWindow.window; } } + public static bool dragging; + + public static void Controls() { Event e = Event.current; switch (e.type) { + case EventType.ScrollWheel: if (e.delta.y > 0) window.zoom += 0.1f * window.zoom; else window.zoom -= 0.1f * window.zoom; break; case EventType.MouseDrag: - if (e.button == 1) window.panOffset += e.delta*window.zoom; + if (e.button == 1) { + window.panOffset += e.delta * window.zoom; + dragging = true; + } break; case EventType.KeyDown: - if (e.keyCode == KeyCode.F) { - window.zoom = 2; - window.panOffset = Vector2.zero; + if (e.keyCode == KeyCode.F) Focus(); + break; + case EventType.mouseDown: + dragging = false; + break; + case EventType.MouseUp: + if (dragging) return; + if (e.button == 1) { + NodeEditorGUI.RightClickContextMenu(); } break; } } + + /// Puts all nodes in focus. If no nodes are present, resets view to + public static void Focus() { + window.zoom = 2; + window.panOffset = Vector2.zero; + } + + public static void CreateNode(Type type, Vector2 position) { + Node node = window.currentGraph.AddNode(type); + Debug.Log("SetNode " + position); + node.position.position = position; + } } diff --git a/Scripts/Editor/NodeEditorGUI.cs b/Scripts/Editor/NodeEditorGUI.cs index 9b42037..ede6754 100644 --- a/Scripts/Editor/NodeEditorGUI.cs +++ b/Scripts/Editor/NodeEditorGUI.cs @@ -2,12 +2,16 @@ using System.Collections.Generic; using UnityEngine; using UnityEditor; +using System; namespace UNEC { /// Contains GUI methods public static class NodeEditorGUI { + public static NodeEditorWindow window { get { return NodeEditorWindow.window; } } + public static void DrawGrid(Rect rect, float zoom, Vector2 panOffset) { + rect.position = Vector2.zero; Vector2 center = rect.size / 2f; @@ -30,5 +34,56 @@ namespace UNEC { GUI.DrawTextureWithTexCoords(rect, gridTex, new Rect(tileOffset, tileAmount)); GUI.DrawTextureWithTexCoords(rect, crossTex, new Rect(tileOffset + new Vector2(0.5f,0.5f), tileAmount)); } + + public static void DrawToolbar() { + EditorGUILayout.BeginHorizontal("Toolbar"); + + if (DropdownButton("File", 50)) FileContextMenu(); + if (DropdownButton("Edit", 50)) EditContextMenu(); + if (DropdownButton("View", 50)) { } + if (DropdownButton("Settings", 70)) { } + if (DropdownButton("Tools", 50)) { } + + // Make the toolbar extend all throughout the window extension. + GUILayout.FlexibleSpace(); + + EditorGUILayout.EndHorizontal(); + } + + public static bool DropdownButton(string name, float width) { + return GUILayout.Button(name, EditorStyles.toolbarDropDown, GUILayout.Width(width)); + } + + public static void RightClickContextMenu() { + GenericMenu contextMenu = new GenericMenu(); + Vector2 pos = window.GetMousePositionOnGrid(); + for (int i = 0; i < NodeEditorReflection.nodeTypes.Length; i++) { + Type type = NodeEditorReflection.nodeTypes[i]; + contextMenu.AddItem(new GUIContent(NodeEditorReflection.nodeTypes[i].ToString()), false, () => { + NodeEditorAction.CreateNode(type, pos); + }); + } + + contextMenu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero)); + } + + public static void FileContextMenu() { + GenericMenu contextMenu = new GenericMenu(); + contextMenu.AddItem(new GUIContent("Create New"), false, null); + contextMenu.AddItem(new GUIContent("Load"), false, null); + + contextMenu.AddSeparator(""); + contextMenu.AddItem(new GUIContent("Save"), false, null); + contextMenu.AddItem(new GUIContent("Save As"), false, null); + + contextMenu.DropDown(new Rect(5f, 17f, 0f, 0f)); + } + + public static void EditContextMenu() { + GenericMenu contextMenu = new GenericMenu(); + contextMenu.AddItem(new GUIContent("Clear"), false, () => window.currentGraph.Clear()); + + contextMenu.DropDown(new Rect(5f, 17f, 0f, 0f)); + } } } \ No newline at end of file diff --git a/Scripts/Editor/NodeEditorReflection.cs b/Scripts/Editor/NodeEditorReflection.cs index c80a6af..2902abd 100644 --- a/Scripts/Editor/NodeEditorReflection.cs +++ b/Scripts/Editor/NodeEditorReflection.cs @@ -7,7 +7,7 @@ namespace UNEC { public static class NodeEditorReflection { public static Type[] nodeTypes { get { return _nodeTypes != null ? _nodeTypes : _nodeTypes = GetNodeTypes(); } } - public static Type[] _nodeTypes; + private static Type[] _nodeTypes; public static Type[] GetNodeTypes() { //Get all classes deriving from Node via reflection diff --git a/Scripts/Editor/NodeEditorResources.cs b/Scripts/Editor/NodeEditorResources.cs index 1372471..ebee646 100644 --- a/Scripts/Editor/NodeEditorResources.cs +++ b/Scripts/Editor/NodeEditorResources.cs @@ -10,10 +10,10 @@ namespace UNEC { private static Texture2D _crossTexture; - private static Color backgroundColor = new Color(0.15f, 0.15f, 0.15f); - private static Color veinColor = new Color(0.2f, 0.2f, 0.2f); - private static Color arteryColor = new Color(0.28f, 0.28f, 0.28f); - private static Color crossColor = new Color(0.4f, 0.4f, 0.4f); + private static Color backgroundColor = new Color(0.18f, 0.18f, 0.18f); + private static Color veinColor = new Color(0.25f, 0.25f, 0.25f); + private static Color arteryColor = new Color(0.34f, 0.34f, 0.34f); + private static Color crossColor = new Color(0.45f, 0.45f, 0.45f); public static Texture2D GenerateGridTexture() { Texture2D tex = new Texture2D(64,64); diff --git a/Scripts/Editor/NodeEditorWindow.cs b/Scripts/Editor/NodeEditorWindow.cs index dc8fae3..c8304b1 100644 --- a/Scripts/Editor/NodeEditorWindow.cs +++ b/Scripts/Editor/NodeEditorWindow.cs @@ -6,23 +6,75 @@ using UNEC; public class NodeEditorWindow : EditorWindow { + + public static NodeEditorWindow window { get { return focusedWindow as NodeEditorWindow; } } + + public NodeGraph currentGraph { get { return _currentGraph != null ? _currentGraph : _currentGraph = new NodeGraph(); }} + public NodeGraph _currentGraph; public Vector2 panOffset { get { return _panOffset; } set { _panOffset = value; Repaint(); } } private Vector2 _panOffset; public float zoom { get { return _zoom; } set { _zoom = Mathf.Clamp(value, 1f, 5f); Repaint(); } } private float _zoom = 1; + [MenuItem("Window/UNEC")] static void Init() { NodeEditorWindow w = CreateInstance(); + w.titleContent = new GUIContent("UNEC"); w.Show(); } private void OnGUI() { + NodeEditorAction.Controls(); - NodeEditorAction.Controls(this); BeginWindows(); NodeEditorGUI.DrawGrid(position, zoom, panOffset); + NodeEditorGUI.DrawToolbar(); + DrawNodes(); EndWindows(); + } -} + + private void DrawNodes() { + Matrix4x4 m = GUI.matrix; + GUI.EndClip(); + GUIUtility.ScaleAroundPivot(Vector2.one / zoom, position.size * 0.5f); + foreach (KeyValuePair kvp in currentGraph.nodes) { + Node node = kvp.Value; + + //Vector2 p = node.position.position + (position.size *0.5f) + panOffset; + //Get node position + Vector2 windowPos = GridToWindowPosition(node.position.position); + windowPos = -windowPos; + + Rect windowRect = new Rect(windowPos, new Vector2(200,200)); + windowRect = GUI.Window(0, windowRect, DraggableWindow, node.ToString()); + //node.position = windowRect.position; + } + GUI.matrix = m; + Vector2 padding = new Vector2(0, 0); + padding *= zoom; + GUI.BeginClip(new Rect( + -(((position.width*zoom) - position.width)*0.5f) + (padding.x), + -(((position.height * zoom) - position.height) * 0.5f) + (padding.y), + (position.width*zoom)- (padding.x * 2), + (position.height * zoom) - (padding.y * 2))); + } + + private void DraggableWindow(int windowID) { + GUI.DragWindow(new Rect(0, 0, 10000, 20)); + } + + public Vector2 GetMousePositionOnGrid() { + return WindowToGridPosition(Event.current.mousePosition); + } + + public Vector2 WindowToGridPosition(Vector2 windowPosition) { + return windowPosition - (window.position.size * 0.5f) - (panOffset * zoom); + } + + public Vector2 GridToWindowPosition(Vector2 gridPosition) { + return ((window.position.size * 0.5f) - (panOffset * zoom)) + gridPosition; + } +} \ No newline at end of file diff --git a/Scripts/Node.cs b/Scripts/Node.cs index 59e21d7..8c8b74c 100644 --- a/Scripts/Node.cs +++ b/Scripts/Node.cs @@ -1,19 +1,8 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -namespace UNEC { - /// Base class for all nodes - public abstract class Node : MonoBehaviour { +using System.Collections; +using System.Collections.Generic; +using UnityEngine; - // Use this for initialization - void Start() { - - } - - // Update is called once per frame - void Update() { - - } - } -} +/// Base class for all nodes +public abstract class Node { + public Rect position = new Rect(0,0,200,200); +} diff --git a/Scripts/NodeGraph.cs b/Scripts/NodeGraph.cs new file mode 100644 index 0000000..b42c2d1 --- /dev/null +++ b/Scripts/NodeGraph.cs @@ -0,0 +1,33 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using System; + +/// Base class for all node graphs +public class NodeGraph { + + public Dictionary nodes = new Dictionary(); + + public T AddNode() where T : Node { + T node = default(T); + nodes.Add(GetGUID(), node); + return node; + } + + public Node AddNode(Type type) { + Node node = (Node)Activator.CreateInstance(type); + if (node == null) return null; + nodes.Add(GetGUID(), node); + return node; + } + + private string GetGUID() { + string guid = Guid.NewGuid().ToString(); + while(nodes.ContainsKey(guid)) guid = GetGUID(); + return guid; + } + + public void Clear() { + nodes.Clear(); + } +} diff --git a/Scripts/NodeGraph.cs.meta b/Scripts/NodeGraph.cs.meta new file mode 100644 index 0000000..b2e1264 --- /dev/null +++ b/Scripts/NodeGraph.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 093f68ef2455d544fa2d14b80c811322 +timeCreated: 1505461376 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: