Ejemplo n.º 1
0
        ///Show the variables of blackboard serialized in contextParent
        public static void ShowVariables(IBlackboard bb, UnityEngine.Object contextParent)
        {
            GUI.skin.label.richText = true;
            var e = Event.current;

            //Begin undo check
            UndoManager.CheckUndo(contextParent, "Blackboard Inspector");

            //Add variable button
            GUI.backgroundColor = Colors.lightBlue;
            if (GUILayout.Button("Add Variable"))
            {
                GetAddVariableMenu(bb).Show(NCPrefs.useBrowser, "Add Variable");
                Event.current.Use();
            }
            GUI.backgroundColor = Color.white;

            //Simple column header info
            if (bb.variables.Keys.Count != 0)
            {
                GUILayout.BeginHorizontal();
                GUI.color = Color.yellow;
                GUILayout.Label("Name", layoutOptions);
                GUILayout.Label("Value", layoutOptions);
                GUI.color = Color.white;
                GUILayout.EndHorizontal();
            }
            else
            {
                EditorGUILayout.HelpBox("Blackboard has no variables", MessageType.Info);
            }


            List <Variable> tempList = null;

            if (!tempLists.TryGetValue(bb, out tempList))
            {
                tempList      = bb.variables.Values.ToList();
                tempLists[bb] = tempList;
            }

            if (!tempList.SequenceEqual(bb.variables.Values))
            {
                tempList      = bb.variables.Values.ToList();
                tempLists[bb] = tempList;
            }

            //store the names of the variables being used by current graph selection.
            var usedVariableNames = GraphEditorUtility.activeElement != null?Graph.GetUsedParameterNamesOfTarget(GraphEditorUtility.activeElement) : new List <string>();

            //The actual variables reorderable list
            var options = new EditorUtils.ReorderableListOptions();

            options.CustomItemMenu = (i) => { return(GetVariableMenu(tempList[i], bb)); };
            EditorUtils.ReorderableList(tempList, options, (i, picked) =>
            {
                var data = (Variable)tempList[i];
                if (data == null)
                {
                    GUILayout.Label("NULL Variable!");
                    return;
                }

                var isUsed = usedVariableNames.Contains(data.name);
                var missingVariableType = data as MissingVariableType;

                GUILayout.Space(data.varType == typeof(VariableSeperator)? 5 : 0);
                GUILayout.BeginHorizontal();

                if (missingVariableType == null)
                {
                    //Name of the variable GUI control
                    if (!Application.isPlaying)
                    {
                        if (picked && data.varType != typeof(VariableSeperator))
                        {
                            pickedVariable           = data;
                            pickedVariableBlackboard = bb;
                        }

                        GUI.color           = Color.white;
                        GUI.backgroundColor = new Color(0.7f, 0.7f, 0.7f, 0.3f);

                        //Make name field red if same name exists
                        if (tempList.Where(v => v != data).Select(v => v.name).Contains(data.name))
                        {
                            GUI.backgroundColor = Color.red;
                        }

                        GUI.enabled = !data.isProtected;
                        if (data.varType != typeof(VariableSeperator))
                        {
                            data.name             = EditorGUILayout.DelayedTextField(data.name, layoutOptions);
                            EditorGUI.indentLevel = 0;
                        }
                        else
                        {
                            var separator = (VariableSeperator)data.value;
                            if (separator == null)
                            {
                                separator = new VariableSeperator();
                            }

                            if (separator.isEditingName)
                            {
                                data.name = EditorGUILayout.DelayedTextField(data.name, layoutOptions);
                            }
                            else
                            {
                                GUI.color = Color.yellow;
                                GUILayout.Label(string.Format("<b>{0}</b>", data.name).ToUpper(), layoutOptions);
                                GUI.color = Color.white;
                            }

                            if (!separator.isEditingName)
                            {
                                if (e.type == EventType.MouseDown && e.button == 0 && e.clickCount == 2 && GUILayoutUtility.GetLastRect().Contains(e.mousePosition))
                                {
                                    separator.isEditingName    = true;
                                    GUIUtility.keyboardControl = 0;
                                }
                            }

                            if (separator.isEditingName)
                            {
                                if ((e.isKey && e.keyCode == KeyCode.Return) || (e.rawType == EventType.MouseUp && !GUILayoutUtility.GetLastRect().Contains(e.mousePosition)))
                                {
                                    separator.isEditingName    = false;
                                    GUIUtility.keyboardControl = 0;
                                }
                            }

                            data.value = separator;
                        }

                        GUI.enabled         = true;
                        GUI.backgroundColor = Color.white;
                    }
                    else
                    {
                        //Don't allow name edits in play mode. Instead show just a label
                        if (data.varType != typeof(VariableSeperator))
                        {
                            GUI.backgroundColor = new Color(0.7f, 0.7f, 0.7f);
                            GUI.color           = new Color(0.8f, 0.8f, 1f);
                            GUILayout.Label(data.name, layoutOptions);
                        }
                        else
                        {
                            GUI.color = Color.yellow;
                            GUILayout.Label(string.Format("<b>{0}</b>", data.name.ToUpper()), layoutOptions);
                            GUI.color = Color.white;
                        }
                    }


                    //reset coloring
                    GUI.color           = Color.white;
                    GUI.backgroundColor = Color.white;

                    //Highlight used variable by selection?
                    if (isUsed)
                    {
                        var highRect   = GUILayoutUtility.GetLastRect();
                        highRect.xMin += 2;
                        highRect.xMax -= 2;
                        highRect.yMax -= 4;
                        GUI.Box(highRect, string.Empty, Styles.highlightBox);
                    }

                    //Show the respective data GUI
                    ShowDataGUI(data, bb, contextParent, layoutOptions);
                }
                else
                {
                    var internalTypeName = missingVariableType.missingType.Split(new string[] { "[[", "]]" }, System.StringSplitOptions.RemoveEmptyEntries)[1];
                    internalTypeName     = internalTypeName.Substring(0, internalTypeName.IndexOf(","));
                    GUILayout.Box(string.Empty, GUILayout.Width(6));
                    GUILayout.Label(data.name, layoutOptions);
                    GUILayout.Label(string.Format("<color=#ff6457>* {0} *</color>", internalTypeName), layoutOptions);
                    if (!Application.isPlaying && GUILayout.Button("x", GUILayout.Width(17), GUILayout.Height(16)))
                    {
                        tempList.Remove(data);
                    }
                }

                //closure
                GUI.color           = Color.white;
                GUI.backgroundColor = Color.white;
                GUILayout.EndHorizontal();
            }, contextParent);

            //reset coloring
            GUI.backgroundColor = Color.white;
            GUI.color           = Color.white;

            if (GUI.changed || e.rawType == EventType.MouseUp)
            {
                EditorApplication.delayCall += () => { ResetPick(); };
                //reconstruct the dictionary
                try { bb.variables = tempList.ToDictionary(d => d.name, d => d); }
                catch { Debug.LogError("Blackboard has duplicate names!"); }
            }

            //Check dirty
            UndoManager.CheckDirty(contextParent);
        }
        public static void ShowVariables(IBlackboard bb, UnityEngine.Object contextParent)
        {
            GUI.skin.label.richText = true;
            var e             = Event.current;
            var layoutOptions = new GUILayoutOption[] { GUILayout.MaxWidth(100), GUILayout.ExpandWidth(true), GUILayout.Height(16) };

            //Begin undo check
            UndoManager.CheckUndo(contextParent, "Blackboard Inspector");

            //Add variable button
            GUI.backgroundColor = new Color(0.8f, 0.8f, 1);
            if (GUILayout.Button("Add Variable"))
            {
                System.Action <System.Type> AddNewVariable = (t) =>
                {
                    var name = "my" + t.FriendlyName();
                    while (bb.GetVariable(name) != null)
                    {
                        name += ".";
                    }
                    bb.AddVariable(name, t);
                };

                System.Action <PropertyInfo> AddBoundProp = (p) =>
                {
                    var newVar = bb.AddVariable(p.Name, p.PropertyType);
                    newVar.BindProperty(p);
                };

                System.Action <FieldInfo> AddBoundField = (f) =>
                {
                    var newVar = bb.AddVariable(f.Name, f.FieldType);
                    newVar.BindProperty(f);
                };

                var menu = new GenericMenu();
                menu = EditorUtils.GetPreferedTypesSelectionMenu(typeof(object), AddNewVariable, true, menu, "New");

                if (bb.propertiesBindTarget != null)
                {
                    foreach (var comp in bb.propertiesBindTarget.GetComponents(typeof(Component)).Where(c => c.hideFlags != HideFlags.HideInInspector))
                    {
                        menu = EditorUtils.GetPropertySelectionMenu(comp.GetType(), typeof(object), AddBoundProp, false, false, menu, "Bound (Self)/Property");
                        menu = EditorUtils.GetFieldSelectionMenu(comp.GetType(), typeof(object), AddBoundField, menu, "Bound (Self)/Field");
                    }
                }

                foreach (var type in UserTypePrefs.GetPreferedTypesList(typeof(object)))
                {
                    menu = EditorUtils.GetStaticPropertySelectionMenu(type, typeof(object), AddBoundProp, false, false, menu, "Bound (Static)/Property");
                    menu = EditorUtils.GetStaticFieldSelectionMenu(type, typeof(object), AddBoundField, menu, "Bound (Static)/Field");
                }


                menu.AddSeparator("/");
                menu.AddItem(new GUIContent("Add Header Separator"), false, () => { bb.AddVariable("Separator (Double Click To Rename)", new VariableSeperator()); });

                menu.ShowAsContext();
                e.Use();
            }


            GUI.backgroundColor = Color.white;

            //Simple column header info
            if (bb.variables.Keys.Count != 0)
            {
                GUILayout.BeginHorizontal();
                GUI.color = Color.yellow;
                GUILayout.Label("Name", layoutOptions);
                GUILayout.Label("Value", layoutOptions);
                GUI.color = Color.white;
                GUILayout.EndHorizontal();
            }
            else
            {
                EditorGUILayout.HelpBox("Blackboard has no variables", MessageType.Info);
            }

            if (!tempStates.ContainsKey(bb))
            {
                tempStates.Add(bb, new ReorderingState(bb.variables.Values.ToList()));
            }

            //Make temporary list for editing variables
            if (!tempStates[bb].isReordering)
            {
                tempStates[bb].list = bb.variables.Values.ToList();
            }

            //store the names of the variables being used by current graph selection.
            var usedVariables = GetUsedVariablesBySelectionParameters();

            //The actual variables reorderable list
            EditorUtils.ReorderableList(tempStates[bb].list, delegate(int i){
                var data = tempStates[bb].list[i];
                if (data == null)
                {
                    GUILayout.Label("NULL Variable!");
                    return;
                }

                var isUsed = usedVariables.Contains(data.name);
                var missingVariableType = data as MissingVariableType;

                GUILayout.Space(data.varType == typeof(VariableSeperator)? 5 : 0);

                GUILayout.BeginHorizontal();

                if (missingVariableType == null)
                {
                    //Name of the variable GUI control
                    if (!Application.isPlaying)
                    {
                        //The small box on the left to re-order variables
                        GUI.backgroundColor = new Color(1, 1, 1, 0.8f);
                        GUILayout.Box("", GUILayout.Width(6));
                        GUI.backgroundColor = new Color(0.7f, 0.7f, 0.7f, 0.3f);

                        if (e.type == EventType.MouseDown && e.button == 0 && GUILayoutUtility.GetLastRect().Contains(e.mousePosition))
                        {
                            tempStates[bb].isReordering = true;
                            if (data.varType != typeof(VariableSeperator))
                            {
                                pickedVariable           = data;
                                pickedVariableBlackboard = bb;
                            }
                        }

                        //Make name field red if same name exists
                        if (tempStates[bb].list.Where(v => v != data).Select(v => v.name).Contains(data.name))
                        {
                            GUI.backgroundColor = Color.red;
                        }

                        GUI.enabled = !data.isProtected;
                        if (data.varType != typeof(VariableSeperator))
                        {
                            data.name = EditorGUILayout.DelayedTextField(data.name, layoutOptions);
                            // data.name = EditorGUILayout.TextField(data.name, layoutOptions);
                            EditorGUI.indentLevel = 0;
                        }
                        else
                        {
                            var separator = (VariableSeperator)data.value;
                            if (separator == null)
                            {
                                separator = new VariableSeperator();
                            }

                            GUI.color = Color.yellow;
                            if (separator.isEditingName)
                            {
                                data.name = EditorGUILayout.DelayedTextField(data.name, layoutOptions);
                                // data.name = EditorGUILayout.TextField(data.name, layoutOptions);
                            }
                            else
                            {
                                GUILayout.Label(string.Format("<b>{0}</b>", data.name).ToUpper(), layoutOptions);
                            }
                            GUI.color = Color.white;

                            if (!separator.isEditingName)
                            {
                                if (e.type == EventType.MouseDown && e.button == 0 && e.clickCount == 2 && GUILayoutUtility.GetLastRect().Contains(e.mousePosition))
                                {
                                    separator.isEditingName    = true;
                                    GUIUtility.keyboardControl = 0;
                                }
                            }

                            if (separator.isEditingName)
                            {
                                if ((e.isKey && e.keyCode == KeyCode.Return) || (e.rawType == EventType.MouseUp && !GUILayoutUtility.GetLastRect().Contains(e.mousePosition)))
                                {
                                    separator.isEditingName    = false;
                                    GUIUtility.keyboardControl = 0;
                                }
                            }

                            data.value = separator;
                        }

                        GUI.enabled         = true;
                        GUI.backgroundColor = Color.white;
                    }
                    else
                    {
                        //Don't allow name edits in play mode. Instead show just a label
                        if (data.varType != typeof(VariableSeperator))
                        {
                            GUI.backgroundColor = new Color(0.7f, 0.7f, 0.7f);
                            GUI.color           = new Color(0.8f, 0.8f, 1f);
                            GUILayout.Label(data.name, layoutOptions);
                        }
                        else
                        {
                            GUI.color = Color.yellow;
                            GUILayout.Label(string.Format("<b>{0}</b>", data.name.ToUpper()), layoutOptions);
                            GUI.color = Color.white;
                        }
                    }


                    //reset coloring
                    GUI.color           = Color.white;
                    GUI.backgroundColor = Color.white;

                    //Highlight used variable by selection?
                    if (isUsed)
                    {
                        var r   = GUILayoutUtility.GetLastRect();
                        r.xMin += 2;
                        r.xMax -= 2;
                        r.yMax -= 4;
                        GUI.Box(r, "", (GUIStyle)"LightmapEditorSelectedHighlight");
                    }

                    //Show the respective data GUI
                    if (data.varType != typeof(VariableSeperator))
                    {
                        ShowDataGUI(data, bb, contextParent, layoutOptions);
                    }
                    else
                    {
                        if (!Application.isPlaying && GUILayout.Button("x", GUILayout.Width(17), GUILayout.Height(16)))
                        {
                            tempStates[bb].list.Remove(data);
                        }
                        GUILayout.Space(0);
                        GUILayout.Space(0);
                    }
                }
                else
                {
                    var internalTypeName = missingVariableType.missingType.Split(new string[] { "[[", "]]" }, System.StringSplitOptions.RemoveEmptyEntries)[1];
                    internalTypeName     = internalTypeName.Substring(0, internalTypeName.IndexOf(","));
                    GUILayout.Box("", GUILayout.Width(6));
                    GUILayout.Label(data.name, layoutOptions);
                    GUILayout.Label(string.Format("<color=#ff6457>* {0} *</color>", internalTypeName), layoutOptions);
                    if (!Application.isPlaying && GUILayout.Button("x", GUILayout.Width(17), GUILayout.Height(16)))
                    {
                        tempStates[bb].list.Remove(data);
                    }
                }

                //reset coloring
                GUI.color           = Color.white;
                GUI.backgroundColor = Color.white;

                GUILayout.EndHorizontal();
            }, contextParent);

            //reset coloring
            GUI.backgroundColor = Color.white;
            GUI.color           = Color.white;


            if ((GUI.changed && !tempStates[bb].isReordering) || e.rawType == EventType.MouseUp)
            {
                tempStates[bb].isReordering  = false;
                EditorApplication.delayCall += () => { pickedVariable = null; pickedVariableBlackboard = null; };
                //reconstruct the dictionary
                try { bb.variables = tempStates[bb].list.ToDictionary(d => d.name, d => d); }
                catch { Debug.LogError("Blackboard has duplicate names!"); }
            }

            //Check dirty
            UndoManager.CheckDirty(contextParent);
        }