public override void DrawWindow(int id)
        {
            EditorGUI.BeginChangeCheck();
            EditorGUI.LabelField(new Rect(5, 35, 50, 20), "Name", QD_DialogueEditor.skin.label);
            string fName = EditorGUI.TextField(new Rect(60, 35, 135, 20), Data.Name, QD_DialogueEditor.skin.textField);

            EditorGUI.LabelField(new Rect(5, 60, 190, 20), "Icon", QD_DialogueEditor.skin.label);
            EditorGUILayout.Space(60);
            Sprite fIcon = (Sprite)EditorGUILayout.ObjectField(Data.Icon, typeof(Sprite), false);

            if (EditorGUI.EndChangeCheck())
            {
                EditorUtility.SetDirty(QD_DialogueEditor.db.DataDB);
                Data.Name = fName;
                Data.Icon = fIcon;

                foreach (var n in QD_DialogueEditor.db.Nodes)
                {
                    if (n.Type == QD_NodeType.Message)
                    {
                        QD_MessageNode messageNode = QD_DialogueEditor.db.GetMessageNode(n.ID);
                        if (messageNode.Data.Speaker == ID)
                        {
                            messageNode.Data.SpeakerName = Data.Name;
                        }
                    }
                }

                QD_DialogueEditor.db.DataDB.SetSpeaker(Data.ID, Data);
            }

            GUI.DragWindow();
        }
        public void ContextCallback(object obj)
        {
            string command = obj.ToString();

            EditorUtility.SetDirty(db);
            EditorUtility.SetDirty(db.DataDB);

            if (command == "Add Conversation")
            {
                db.CreateNode(QD_NodeType.Conversation, mouse + scroll);
            }
            else if (command == "Add Speaker")
            {
                db.CreateNode(QD_NodeType.Speaker, mouse + scroll);
            }
            else if (command == "Add Message")
            {
                db.CreateNode(QD_NodeType.Message, mouse + scroll);
            }
            else if (command == "Add Choice")
            {
                db.CreateNode(QD_NodeType.Choice, mouse + scroll);
            }
            else if (command == "Attach to Node")
            {
                connectingNodes = true;
            }
            else if (command == "Detach All Connected Nodes")
            {
                DetachNodes();
            }
            else if (command == "Detach Connected Nodes")
            {
                DetachNodes(selectedKnob, knobType);
            }
            else if (command == "Delete Node")
            {
                DetachNodes();

                int     i    = db.GetNodeIndex(selectedNode.ID);
                QD_Node node = db.Nodes[i];
                if (node.Type == QD_NodeType.Speaker)
                {
                    db.SpeakerNodes.RemoveAt(db.GetSpeakerNodeIndex(selectedNode.ID));
                }
                else if (node.Type == QD_NodeType.Message)
                {
                    db.MessageNodes.RemoveAt(db.GetMessageNodeIndex(selectedNode.ID));
                }
                else if (node.Type == QD_NodeType.Conversation)
                {
                    db.ConversationNodes.RemoveAt(db.GetConversationNodeIndex(selectedNode.ID));
                }
                else if (node.Type == QD_NodeType.Choice)
                {
                    db.ChoiceNodes.RemoveAt(db.GetChoiceNodeIndex(selectedNode.ID));
                }
                db.Nodes.RemoveAt(i);
                if (node.Type == QD_NodeType.Speaker)
                {
                    foreach (var n in db.Nodes)
                    {
                        if (n.Type == QD_NodeType.Message)
                        {
                            QD_MessageNode messageNode = db.GetMessageNode(n.ID);
                            if (messageNode.Data.Speaker == node.ID)
                            {
                                messageNode.Data.Speaker     = -1;
                                messageNode.Data.SpeakerName = "";
                            }
                        }
                    }

                    i = db.DataDB.GetSpeakerIndex(selectedNode.ID);
                    db.DataDB.Speakers.RemoveAt(i);
                }
                else if (node.Type == QD_NodeType.Message)
                {
                    i = db.DataDB.GetMessageIndex(selectedNode.ID);
                    db.DataDB.Messages.RemoveAt(i);
                }
                else if (node.Type == QD_NodeType.Conversation)
                {
                    i = db.DataDB.GetConversationIndex(selectedNode.ID);
                    db.DataDB.Conversations.RemoveAt(i);
                }
                else if (node.Type == QD_NodeType.Choice)
                {
                    i = db.DataDB.GetChoiceIndex(selectedNode.ID);
                    db.DataDB.Choices.RemoveAt(i);
                }
                if (db.Nodes.Count == 0)
                {
                    db.NextID = 0;
                }
            }
        }
        private void OnGUI()
        {
            if (!editor)
            {
                editor = this;
            }
            SelectDB();
            skin     = Resources.Load <GUISkin>("Node Editor Skin");
            GUI.skin = skin;
            float eWidth  = editor.position.width;
            float eHeight = editor.position.height;

            if (!db)
            {
                EditorGUILayout.HelpBox("Select an object with a QD_NodeDB script.", MessageType.Info);
            }
            else
            {
                Event e = Event.current;
                mouse = e.mousePosition;
                int nodeCount = db.Nodes.Count;

                // Mouse click events, taken from https://forum.unity.com/threads/simple-node-editor.189230/
                if (e.type == EventType.MouseDown && e.button == 1 && !connectingNodes)
                {
                    bool clicked           = false;
                    int  selectedIndex     = -1;
                    bool knobClicked       = false;
                    int  knobSelectedIndex = -1;

                    for (int i = 0; i < nodeCount; ++i)
                    {
                        QD_Node node = db.Nodes[i];
                        if (node.Window.Contains(mouse + scroll))
                        {
                            selectedIndex = i;
                            clicked       = true;
                            break;
                        }
                        else
                        {
                            int inputCount = node.Inputs.Count;
                            for (int j = 0; j < inputCount; ++j)
                            {
                                if (node.InputKnob(j).Contains(mouse + scroll))
                                {
                                    selectedIndex     = i;
                                    clicked           = true;
                                    knobSelectedIndex = j;
                                    knobClicked       = true;
                                    knobType          = QD_KnobType.Input;
                                    selectedKnob      = j;
                                    break;
                                }
                            }

                            if (knobClicked)
                            {
                                break;
                            }

                            int outputCount = node.Outputs.Count;
                            for (int j = 0; j < outputCount; ++j)
                            {
                                if (node.OutputKnob(j).Contains(mouse + scroll))
                                {
                                    selectedIndex     = i;
                                    clicked           = true;
                                    knobSelectedIndex = j;
                                    knobClicked       = true;
                                    knobType          = QD_KnobType.Output;
                                    selectedKnob      = j;
                                    break;
                                }
                            }

                            if (knobClicked)
                            {
                                break;
                            }
                        }
                    }

                    if (!clicked)
                    {
                        GenericMenu menu = new GenericMenu();
                        menu.AddItem(new GUIContent("Add Conversation"), false, ContextCallback, "Add Conversation");
                        menu.AddItem(new GUIContent("Add Speaker"), false, ContextCallback, "Add Speaker");
                        menu.AddItem(new GUIContent("Add Message"), false, ContextCallback, "Add Message");
                        menu.AddItem(new GUIContent("Add Choice"), false, ContextCallback, "Add Choice");
                        menu.ShowAsContext();
                        e.Use();
                    }
                    else
                    {
                        GenericMenu menu = new GenericMenu();
                        if (!knobClicked)
                        {
                            menu.AddItem(new GUIContent("Detach All Connected Nodes"), false, ContextCallback, "Detach All Connected Nodes");
                            menu.AddItem(new GUIContent("Delete Node"), false, ContextCallback, "Delete Node");
                        }
                        else
                        {
                            menu.AddItem(new GUIContent("Attach to Node"), false, ContextCallback, "Attach to Node");
                            menu.AddItem(new GUIContent("Detach Connected Nodes"), false, ContextCallback, "Detach Connected Nodes");
                        }
                        menu.ShowAsContext();
                        e.Use();
                        selectedNode = db.Nodes[selectedIndex];
                    }
                }
                else if (e.type == EventType.MouseDown && e.button == 0 && connectingNodes)
                {
                    bool        clicked           = false;
                    int         selectedIndex     = -1;
                    bool        knobClicked       = false;
                    int         knobSelectedIndex = -1;
                    QD_KnobType clickedKnobType   = QD_KnobType.Input;

                    for (int i = 0; i < nodeCount; ++i)
                    {
                        QD_Node node       = db.Nodes[i];
                        int     inputCount = node.Inputs.Count;
                        for (int j = 0; j < inputCount; ++j)
                        {
                            if (node.InputKnob(j).Contains(mouse + scroll))
                            {
                                selectedIndex     = i;
                                clicked           = true;
                                knobSelectedIndex = j;
                                knobClicked       = true;
                                clickedKnobType   = QD_KnobType.Input;
                                break;
                            }
                        }

                        if (knobClicked)
                        {
                            break;
                        }

                        int outputCount = node.Outputs.Count;
                        for (int j = 0; j < outputCount; ++j)
                        {
                            if (node.OutputKnob(j).Contains(mouse + scroll))
                            {
                                selectedIndex     = i;
                                clicked           = true;
                                knobSelectedIndex = j;
                                knobClicked       = true;
                                clickedKnobType   = QD_KnobType.Output;
                                break;
                            }
                        }

                        if (knobClicked)
                        {
                            break;
                        }
                    }

                    if (clicked)
                    {
                        EditorUtility.SetDirty(db);
                        if (knobType == QD_KnobType.Input && clickedKnobType == QD_KnobType.Output)
                        {
                            QD_Node outputNode = db.Nodes[selectedIndex];
                            QD_Knob input      = selectedNode.Inputs[selectedKnob];
                            QD_Knob output     = outputNode.Outputs[knobSelectedIndex];
                            if (selectedNode.ID != outputNode.ID &&
                                (!output.Connections.ContainsKey(selectedNode.ID) || !output.Connections.Get(selectedNode.ID).Contains(selectedKnob)) &&
                                (!input.Connections.ContainsKey(outputNode.ID) || !input.Connections.Get(outputNode.ID).Contains(knobSelectedIndex)) &&
                                (output.AllowMultipleConnections || output.Connections.Count == 0) &&
                                (input.AllowMultipleConnections || input.Connections.Count == 0) &&
                                selectedNode.CanConnect(knobType, selectedKnob, outputNode.Type, QD_KnobType.Output, knobSelectedIndex)
                                )
                            {
                                selectedNode.ConnectNode(outputNode.ID, knobSelectedIndex, selectedKnob, QD_KnobType.Input);
                                outputNode.ConnectNode(selectedNode.ID, selectedKnob, knobSelectedIndex, QD_KnobType.Output);
                            }
                        }
                        else if (knobType == QD_KnobType.Output && clickedKnobType == QD_KnobType.Input)
                        {
                            QD_Node inputNode = db.Nodes[selectedIndex];
                            QD_Knob input     = inputNode.Inputs[knobSelectedIndex];
                            QD_Knob output    = selectedNode.Outputs[selectedKnob];
                            if (selectedNode.ID != inputNode.ID &&
                                (!output.Connections.ContainsKey(inputNode.ID) || !output.Connections.Get(inputNode.ID).Contains(knobSelectedIndex)) &&
                                (!input.Connections.ContainsKey(selectedNode.ID) || !input.Connections.Get(selectedNode.ID).Contains(selectedKnob)) &&
                                (output.AllowMultipleConnections || output.Connections.Count == 0) &&
                                (input.AllowMultipleConnections || input.Connections.Count == 0) &&
                                selectedNode.CanConnect(knobType, selectedKnob, inputNode.Type, QD_KnobType.Input, knobSelectedIndex)
                                )
                            {
                                selectedNode.ConnectNode(inputNode.ID, knobSelectedIndex, selectedKnob, QD_KnobType.Output);
                                inputNode.ConnectNode(selectedNode.ID, selectedKnob, knobSelectedIndex, QD_KnobType.Input);
                            }
                        }
                    }

                    connectingNodes = false;
                    selectedNode    = null;
                    knobClicked     = false;
                    selectedKnob    = -1;
                    e.Use();
                }
                if (connectingNodes && selectedNode != null)
                {
                    Rect mouseRect = new Rect(e.mousePosition.x, e.mousePosition.y, 10, 10);
                    Rect knobRect  = knobType == QD_KnobType.Input ? selectedNode.InputKnob(selectedKnob) : selectedNode.OutputKnob(selectedKnob);
                    knobRect.position += new Vector2(knobRect.width / 2, knobRect.height / 2) - scroll;
                    DrawNodeCurve(knobType == QD_KnobType.Output ? knobRect : mouseRect, knobType == QD_KnobType.Output ? mouseRect : knobRect, false);
                    Repaint();
                }

                GUILayout.BeginArea(new Rect(-scroll, new Vector2(5000, 5000)));

                for (int i = 0; i < nodeCount; ++i)
                {
                    QD_Node node        = db.Nodes[i];
                    int     outputCount = node.Outputs.Count;
                    for (int j = 0; j < outputCount; ++j)
                    {
                        QD_Knob output = node.Outputs[j];
                        if (output.Connections.Count > 0)
                        {
                            foreach (KeyValuePair <int, List <int> > connection in output.Connections.dictionary)
                            {
                                int connectionCount = connection.Value.Count;
                                for (int k = 0; k < connectionCount; ++k)
                                {
                                    DrawNodeCurve(node.OutputKnob(j), db.GetNode(connection.Key).InputKnob(connection.Value[k]), true);
                                }
                            }
                        }
                    }
                }

                BeginWindows();
                for (int i = 0; i < nodeCount; ++i)
                {
                    QD_Node node = db.Nodes[i];
                    if (node.Type == QD_NodeType.Speaker)
                    {
                        QD_SpeakerNode realNode = db.GetSpeakerNode(node.ID);
                        node.Window = GUI.Window(node.ID, node.Window, realNode.DrawWindow, realNode.WindowTitle);
                    }
                    else if (node.Type == QD_NodeType.Message)
                    {
                        QD_MessageNode realNode = db.GetMessageNode(node.ID);
                        node.Window = GUI.Window(node.ID, node.Window, realNode.DrawWindow, realNode.WindowTitle);
                    }
                    else if (node.Type == QD_NodeType.Conversation)
                    {
                        QD_ConversationNode realNode = db.GetConversationNode(node.ID);
                        node.Window = GUI.Window(node.ID, node.Window, realNode.DrawWindow, realNode.WindowTitle);
                    }
                    else if (node.Type == QD_NodeType.Choice)
                    {
                        QD_ChoiceNode realNode = db.GetChoiceNode(node.ID);
                        node.Window = GUI.Window(node.ID, node.Window, realNode.DrawWindow, realNode.WindowTitle);
                    }
                    node.DrawKnobs();
                }
                EndWindows();

                GUILayout.EndArea();

                scroll = new Vector2(
                    GUI.HorizontalScrollbar(new Rect(0, eHeight - 15, eWidth - 15, eHeight - 5), scroll.x, eHeight, 0, 5000),
                    GUI.VerticalScrollbar(new Rect(eWidth - 15, 0, eWidth - 5, eHeight - 15), scroll.y, eHeight, 0, 5000)
                    );
            }
        }
Exemple #4
0
        /// <summary>
        /// Creates a new node of the given type at the given position.
        /// </summary>
        /// <param name="type"></param>
        /// <param name="position"></param>
        public void CreateNode(QD_NodeType type, Vector2 position)
        {
            int id   = NextID++;
            var node = new QD_Node(id, type, position.x, position.y);

            if (type == QD_NodeType.Speaker)
            {
                var speakerNode = new QD_SpeakerNode(id, type, position.x, position.y);

                node.Window.width   = speakerNode.Window.width;
                node.Window.height  = speakerNode.Window.height;
                node.Inputs         = speakerNode.CloneKnobs(QD_KnobType.Input);
                node.Outputs        = speakerNode.CloneKnobs(QD_KnobType.Output);
                node.AllowedInputs  = speakerNode.AllowedInputs;
                node.AllowedOutputs = speakerNode.AllowedOutputs;

                var speakerData = new QD_Speaker(id);
                DataDB.Speakers.Add(speakerData);
                speakerNode.Data = speakerData;

                SpeakerNodes.Add(speakerNode);
            }
            else if (type == QD_NodeType.Message)
            {
                var messageNode = new QD_MessageNode(id, type, position.x, position.y);

                node.Window.width   = messageNode.Window.width;
                node.Window.height  = messageNode.Window.height;
                node.Inputs         = messageNode.CloneKnobs(QD_KnobType.Input);
                node.Outputs        = messageNode.CloneKnobs(QD_KnobType.Output);
                node.AllowedInputs  = messageNode.AllowedInputs;
                node.AllowedOutputs = messageNode.AllowedOutputs;

                var messageData = new QD_Message(id);
                DataDB.Messages.Add(messageData);
                messageNode.Data = messageData;

                MessageNodes.Add(messageNode);
            }
            else if (type == QD_NodeType.Conversation)
            {
                var conversationNode = new QD_ConversationNode(id, type, position.x, position.y);

                node.Window.width   = conversationNode.Window.width;
                node.Window.height  = conversationNode.Window.height;
                node.Inputs         = conversationNode.CloneKnobs(QD_KnobType.Input);
                node.Outputs        = conversationNode.CloneKnobs(QD_KnobType.Output);
                node.AllowedInputs  = conversationNode.AllowedInputs;
                node.AllowedOutputs = conversationNode.AllowedOutputs;

                var conversationData = new QD_Conversation(id);
                DataDB.Conversations.Add(conversationData);
                conversationNode.Data = conversationData;

                ConversationNodes.Add(conversationNode);
            }
            else if (type == QD_NodeType.Choice)
            {
                var choiceNode = new QD_ChoiceNode(id, type, position.x, position.y);

                node.Window.width   = choiceNode.Window.width;
                node.Window.height  = choiceNode.Window.height;
                node.Inputs         = choiceNode.CloneKnobs(QD_KnobType.Input);
                node.Outputs        = choiceNode.CloneKnobs(QD_KnobType.Output);
                node.AllowedInputs  = choiceNode.AllowedInputs;
                node.AllowedOutputs = choiceNode.AllowedOutputs;

                var choiceData = new QD_Choice(id);
                DataDB.Choices.Add(choiceData);
                choiceNode.Data = choiceData;

                ChoiceNodes.Add(choiceNode);
            }

            Nodes.Add(node);
        }