public override void OnDetailsGUI()
        {
            Type   type     = VariableType;
            string name     = VariableName;
            bool   isGet    = IsGetVariable;
            float  maxWidth = GUILayoutUtility.GetRect(0, Screen.width, 0, 0).width;

            FlowGraphEditorWindow.detailsNameStyle.LabelFit(new GUIContent(IsGetVariable ? "Get Variable" : "Set Variable"), (int)maxWidth);

            var variable = Graph.GetVariable(name);

            using (new GUILayout.HorizontalScope())
            {
                if (variable == null)
                {
                    GUI.color = Color.red;
                }
                GUILayout.Label("Name", GUILayout.Width(EditorGUIUtility.labelWidth));
                GUI.color = Color.white;
                GUILayout.Label(name);
            }

            using (new GUILayout.HorizontalScope())
            {
                if (variable != null && variable.Type != type)
                {
                    GUI.color = Color.red;
                }
                GUILayout.Label("Type", GUILayout.Width(EditorGUIUtility.labelWidth));
                GUI.color = Color.white;
                GUILayout.Label(FlowNode.GetDisplayValueTypeName(type));
            }
        }
        public override void OnNodeNameGUI(Rect rect, GUIStyle labelStyle)
        {
            FlowNode   node    = target as FlowNode;
            string     varName = VariableName;
            Type       varType = VariableType;
            GUIContent content;

            content = new GUIContent("$" + varName, "Get Variable(" + FlowNode.GetDisplayValueTypeName(varType) + ")");

            var variable = Graph.GetVariable(varName);

            if (variable == null)
            {
                content.tooltip = string.Format("not variable '{0}'", varName);
                GUI.color       = Color.red;
            }
            else
            {
                if (variable.Type != varType)
                {
                    content.tooltip = string.Format("variable type no match", variable.Type, varType);
                    GUI.color       = Color.red;
                }
            }


            labelStyle.LabelFit(rect, content);
            GUI.color = Color.white;
        }
        public override void OnDetailsGUI()
        {
            Type valueType = ValueType;

            float maxWidth = GUILayoutUtility.GetRect(0, Screen.width, 0, 0).width;

            FlowGraphEditorWindow.detailsNameStyle.LabelFit(new GUIContent("Value"), (int)maxWidth);

            using (new GUILayout.HorizontalScope())
            {
                GUILayout.Label("Type", GUILayout.Width(EditorGUIUtility.labelWidth));
                GUILayout.Label(FlowNode.GetDisplayValueTypeName(valueType));
            }
        }
        public override void OnNodeNameGUI(Rect rect, GUIStyle labelStyle)
        {
            Type     valueType   = ValueType;
            object   value       = Value;
            TypeCode typeCode    = Type.GetTypeCode(valueType);
            string   nameTooltip = FlowNode.GetDisplayValueTypeName(valueType) + " Value";
            bool     doubleClick = false;
            Event    evt         = Event.current;

            if (evt.type == EventType.MouseUp)
            {
                if (rect.Contains(evt.mousePosition))
                {
                    if (EditorApplication.timeSinceStartup - lastClickCount < 0.2f)
                    {
                        doubleClick = true;
                    }
                    lastClickCount = EditorApplication.timeSinceStartup;
                }
            }
            else if (evt.type == EventType.KeyDown)
            {
                if (evt.keyCode == KeyCode.Escape)
                {
                    if (isEditing)
                    {
                        isEditing = false;
                        evt.Use();
                    }
                }
            }

            if (!selected)
            {
                isEditing = false;
            }
            string valueStr = string.Empty;

            if (value != null)
            {
                valueStr = value.ToString();
            }
            bool changed = false;

            using (var check = new EditorGUI.ChangeCheckScope())
            {
                switch (typeCode)
                {
                case TypeCode.String:
                {
                    if (!isEditing)
                    {
                        labelStyle.LabelFit(rect, new GUIContent(valueStr, nameTooltip));
                        if (doubleClick)
                        {
                            isEditing = true;
                        }
                    }
                    else
                    {
                        value = EditorGUI.DelayedTextField(rect, valueStr);
                    }
                }
                break;

                case TypeCode.Boolean:
                {
                    if (!isEditing)
                    {
                        labelStyle.LabelFit(rect, new GUIContent(valueStr, nameTooltip));
                        if (doubleClick)
                        {
                            isEditing = true;
                        }
                    }
                    else
                    {
                        value = EditorGUI.ToggleLeft(rect, new GUIContent(valueStr, nameTooltip), (bool)value);
                    }
                }
                break;

                case TypeCode.Int32:
                {
                    if (!isEditing)
                    {
                        labelStyle.LabelFit(rect, new GUIContent(valueStr, nameTooltip));
                        if (doubleClick)
                        {
                            isEditing = true;
                        }
                    }
                    else
                    {
                        value = EditorGUI.DelayedIntField(rect, (int)value);
                    }
                }
                break;

                case TypeCode.Single:
                {
                    if (!isEditing)
                    {
                        labelStyle.LabelFit(rect, new GUIContent(valueStr, nameTooltip));
                        if (doubleClick)
                        {
                            isEditing = true;
                        }
                    }
                    else
                    {
                        value = EditorGUI.DelayedFloatField(rect, (float)value);
                    }
                }
                break;

                default:
                {
                    if (valueType == typeof(Object) || valueType.IsSubclassOf(typeof(UnityEngine.Object)))
                    {
                        value = EditorGUI.ObjectField(rect, GUIContent.none, (Object)value, valueType, true);
                    }
                    else if (valueType == typeof(Color))
                    {
                        value = EditorGUI.ColorField(rect, GUIContent.none, (Color)value, false, true, false);
                    }
                    else if (valueType == typeof(AnimationCurve))
                    {
                        value = EditorGUI.CurveField(rect, (AnimationCurve)value);
                    }
                    else if (valueType == typeof(Vector2))
                    {
                        value = EditorGUI.Vector2Field(rect, GUIContent.none, (Vector2)value);
                    }
                    else if (valueType == typeof(Vector2Int))
                    {
                        value = EditorGUI.Vector2IntField(rect, GUIContent.none, (Vector2Int)value);
                    }
                    else if (valueType == typeof(Vector3))
                    {
                        value = EditorGUI.Vector3Field(rect, GUIContent.none, (Vector3)value);
                    }
                    else if (valueType == typeof(Vector3Int))
                    {
                        value = EditorGUI.Vector3IntField(rect, GUIContent.none, (Vector3Int)value);
                    }
                    else if (valueType == typeof(Vector4))
                    {
                        value = EditorGUI.Vector4Field(rect, GUIContent.none, (Vector4)value);
                    }
                    else
                    {
                        labelStyle.LabelFit(rect, new GUIContent(valueStr, nameTooltip));
                    }
                }
                break;
                }
                if (check.changed)
                {
                    Value       = value;
                    GUI.changed = false;
                    isEditing   = false;
                    changed     = true;
                }
            }
            if (changed)
            {
                GUI.changed = true;
            }
            EditorGUI.LabelField(rect, new GUIContent(string.Empty, nameTooltip));
        }
        public static List <VariableInfo> DrawVariables(Rect position, IEnumerable <VariableInfo> variables, Dictionary <string, VariableInfo> ovrrideInputs, List <VariableInfo> inputs)
        {
            if (inputs != null)
            {
                for (int i = 0; i < inputs.Count; i++)
                {
                    var input    = inputs[i];
                    var variable = variables.Where(o => o.Name == input.Name).FirstOrDefault();
                    if (variable == null || variable.Type != input.Type)
                    {
                        inputs.RemoveAt(i);
                        i--;
                        GUI.changed = true;
                    }
                }
            }

            Rect rowRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight);

            GUIStyle labelStyle = new GUIStyle("label");
            //    labelStyle.fontStyle = FontStyle.Bold;

            int inputCount = variables.Where(o => o.IsIn).Count();
            // if (inputCount > 0)
            {
                rowRect.x     = position.x;
                rowRect.width = position.width;
                rowRect.xMin += GUI.depth * GUIDepthScope.Pixels;

                //rowRect = EditorGUI.PrefixLabel(rowRect, new GUIContent("Input"), labelStyle);
                GUI.Label(GUIExtensions.Width(ref rowRect, EditorGUIUtility.labelWidth), new GUIContent("Input"), labelStyle);
                rowRect.y += rowRect.height;
                using (new GUIDepthScope())
                {
                    variables.Where(o => o.IsIn).OrderBy(o => o.Name).Where((variable, index) =>
                    {
                        VariableInfo inVar = null;

                        if (inputs != null)
                        {
                            inVar = inputs.Where(o => o.Name == variable.Name).FirstOrDefault();
                        }

                        if (inVar != null && inVar.Type != variable.Type)
                        {
                            inputs.Remove(inVar);
                            inVar       = null;
                            GUI.changed = true;
                        }


                        rowRect.x     = position.x;
                        rowRect.width = position.width;
                        rowRect.xMin += GUI.depth * GUIDepthScope.Pixels;

                        if (inVar == null)
                        {
                            GUI.color = Color.gray;
                        }
                        else
                        {
                            GUI.color = Color.white;
                        }
                        GUI.Label(GUIExtensions.Width(ref rowRect, variableLabelWidth), new GUIContent(variable.Name));

                        GUI.color = Color.white;

                        var tmpRect = GUIExtensions.Width(ref rowRect, rowRect.width - variableCheckWidth);
                        if (inVar != null)
                        {
                            object newValue2;

                            newValue2 = SerializableValuePropertyDrawer.ValueField(tmpRect, inVar.DefaultValue, inVar.Type);
                            if (!object.Equals(newValue2, inVar.DefaultValue))
                            {
                                inVar.DefaultValue = newValue2;
                                GUI.changed        = true;
                            }
                        }
                        else
                        {
                            GUI.enabled = false;

                            object value = variable.DefaultValue;
                            if (ovrrideInputs.ContainsKey(variable.Name))
                            {
                                value = ovrrideInputs[variable.Name].DefaultValue;
                            }
                            SerializableValuePropertyDrawer.ValueField(tmpRect, value, variable.Type);
                            GUI.enabled = true;
                        }


                        rowRect.xMin += 5f;

                        if (EditorGUI.Toggle(rowRect, inVar != null))
                        {
                            if (inVar == null)
                            {
                                inVar = new VariableInfo(variable.Name, variable.Type, variable.DefaultValue);
                                if (inputs == null)
                                {
                                    inputs = new List <VariableInfo>();
                                }
                                inputs.Add(inVar);
                                GUI.changed = true;
                            }
                        }
                        else
                        {
                            if (inVar != null)
                            {
                                inputs.Remove(inVar);
                                GUI.changed = true;
                            }
                        }

                        rowRect.y = rowRect.yMax;
                        return(false);
                    }).Count();
                }
            }

            int outputCount = variables.Where(o => o.IsOut).Count();

            //     if (outputCount > 0)
            {
                rowRect.x     = position.x;
                rowRect.width = position.width;
                rowRect.xMin += GUI.depth * GUIDepthScope.Pixels;
                //rowRect = EditorGUI.PrefixLabel(rowRect, new GUIContent("Output"), labelStyle);

                GUI.Label(GUIExtensions.Width(ref rowRect, EditorGUIUtility.labelWidth), new GUIContent("Output"), labelStyle);
                rowRect.y += rowRect.height;

                using (new GUIDepthScope())
                {
                    variables.Where(o => o.IsOut).OrderBy(o => o.Name).Where((variable, index) =>
                    {
                        rowRect.x     = position.x;
                        rowRect.width = position.width;
                        rowRect.xMin += GUI.depth * GUIDepthScope.Pixels;

                        GUI.Label(GUIExtensions.Width(ref rowRect, variableLabelWidth), new GUIContent(variable.Name));
                        GUI.Label(rowRect, new GUIContent(FlowNode.GetDisplayValueTypeName(variable.Type), variable.Type.FullName));
                        rowRect.y += rowRect.height;
                        return(false);
                    }).Count();
                }
            }
            return(inputs);
        }