private void _GUI_AddNewCurve()
        {
            EditorWindow uaw      = (EditorWindow)EUtil.GetUnityAnimationWindow();
            object       uawstate = EUtil.GetUnityAnimationWindowState(uaw);

            m_CurClip = RCall.GetProp("UnityEditorInternal.AnimationWindowState",
                                      "activeAnimationClip", uawstate) as AnimationClip;

            if (m_CurClip == null)
            {
                EditorGUILayout.LabelField("Need an animation clip first...");
                return;
            }

            m_NewPath      = EditorGUILayout.TextField("Path:", m_NewPath);
            m_NewProperty  = EditorGUILayout.TextField("Property:", m_NewProperty);
            m_TypeFullName = EditorGUILayout.TextField("TypeFullName:", m_TypeFullName);
            m_bIsPPtrCurve = EditorGUILayout.Toggle("IsPPtrCurve:", m_bIsPPtrCurve);

            EditorGUILayout.Separator();

            bool bOK = true;

            EUtil.PushGUIColor(Color.red);
            if (string.IsNullOrEmpty(m_NewProperty))
            {
                bOK = false;
                EditorGUILayout.LabelField("Property is not specified");
            }
            if (string.IsNullOrEmpty(m_TypeFullName) || RCall.GetTypeFromString(m_TypeFullName, true) == null)
            {
                bOK = false;
                EditorGUILayout.LabelField(string.Format("No type is found for name: {0}", m_TypeFullName));
            }
            EUtil.PopGUIColor();

            EUtil.PushGUIEnable(bOK);
            {
                if (EUtil.Button("Add New Curve", Color.green))
                {
                    Type tp = RCall.GetTypeFromString(m_TypeFullName);
                    if (m_bIsPPtrCurve)
                    {
                        EditorCurveBinding newBinding = EditorCurveBinding.PPtrCurve(m_NewPath, tp, m_NewProperty);
                        AnimationUtility.SetObjectReferenceCurve(m_CurClip, newBinding, new ObjectReferenceKeyframe[0]);
                    }
                    else
                    {
                        EditorCurveBinding newBinding = EditorCurveBinding.FloatCurve(m_NewPath, tp, m_NewProperty);
                        AnimationUtility.SetEditorCurve(m_CurClip, newBinding, new AnimationCurve());
                    }
                }
            }
            EUtil.PopGUIEnable();
        }
        private void _GUI_EditSingleCurve()
        {
            EditorWindow uaw      = (EditorWindow)EUtil.GetUnityAnimationWindow();
            object       uawstate = EUtil.GetUnityAnimationWindowState(uaw);

            m_CurClip = RCall.GetField("UnityEditorInternal.AnimationWindowState",
                                       "m_ActiveAnimationClip", uawstate) as AnimationClip;

            IList curves = (IList)RCall.GetProp("UnityEditorInternal.AnimationWindowState", "activeCurves", uawstate);

            if (curves.Count != 1)
            {
                EditorGUILayout.LabelField(string.Format("Please select ONE curve, you have currently selected {0} curves", curves.Count));
                return;
            }

            object             oneCurve   = curves[0]; //AnimationWindowCurve
            EditorCurveBinding oneBinding = (EditorCurveBinding)RCall.GetProp("UnityEditorInternal.AnimationWindowCurve", "binding", oneCurve);

            EditorGUILayout.LabelField("Path:");
            EUtil.PushContentColor(Color.yellow);
            EditorGUILayout.SelectableLabel(oneBinding.path);
            EUtil.PopContentColor();

            EditorGUILayout.LabelField("Property:");
            EUtil.PushContentColor(Color.green);
            EditorGUILayout.SelectableLabel(oneBinding.propertyName);
            EUtil.PopContentColor();

            EditorGUILayout.LabelField("IsPPtrCurve:  " + oneBinding.isPPtrCurve.ToString());

            EditorGUILayout.Separator();

            m_NewType = EditorGUILayout.TextField("Type:", m_NewType);
            if (m_NewType.Length == 0)
            {
                m_NewType = oneBinding.type.ToString();
            }

            m_NewPath     = EditorGUILayout.TextField("New Path:", m_NewPath);
            m_NewProperty = EditorGUILayout.TextField("New Property:", m_NewProperty);

            Type newTp = RCall.GetTypeFromString(m_NewType, true);

            EUtil.PushGUIEnable(m_NewProperty.Length > 0 && newTp != null);
            if (EUtil.Button("Apply Change", Color.green))
            {
                Undo.RegisterCompleteObjectUndo(m_CurClip, "Apply Curve Change");
                _ModifyCurveBinding(oneBinding, m_NewPath, m_NewProperty, newTp);
            }
            EUtil.PopGUIEnable();
        }
        private void _GUI_BatchAddPrefix()
        {
            EditorWindow uaw      = (EditorWindow)EUtil.GetUnityAnimationWindow();
            object       uawstate = EUtil.GetUnityAnimationWindowState(uaw);

            m_CurClip = RCall.GetField("UnityEditorInternal.AnimationWindowState",
                                       "m_ActiveAnimationClip", uawstate) as AnimationClip;

            //1. collect the TrPaths from active curves
            List <BindingInfo> bindingInfos = new List <BindingInfo>();

            IList curves = (IList)RCall.GetProp("UnityEditorInternal.AnimationWindowState", "activeCurves", uawstate);

            for (int idx = 0; idx < curves.Count; ++idx)
            {
                object             oneCurve   = curves[idx]; //AnimationWindowCurve
                EditorCurveBinding oneBinding = (EditorCurveBinding)RCall.GetProp("UnityEditorInternal.AnimationWindowCurve", "binding", oneCurve);
                bindingInfos.Add(new BindingInfo(oneBinding, oneCurve));
            }

            //2. display
            EditorGUILayout.LabelField("Selected curves:");
            m_scrollPos = EditorGUILayout.BeginScrollView(m_scrollPos, false, true, GUILayout.Height(200f));
            {
                foreach (var oneInfo in bindingInfos)
                {
                    EditorCurveBinding oneBinding = oneInfo.m_Binding;
                    GUILayout.BeginHorizontal();
                    {
                        EUtil.PushContentColor(Color.yellow);
                        GUILayout.Label(oneBinding.path);
                        EUtil.PopContentColor();
                        EUtil.PushContentColor(Color.green);
                        GUILayout.Label(oneBinding.propertyName);
                        EUtil.PopContentColor();
                    }
                    GUILayout.EndHorizontal();
                }
            }
            EditorGUILayout.EndScrollView();

            //3. apply prefix
            m_Prefix = EditorGUILayout.TextField("Prefix:", m_Prefix);

            EUtil.PushGUIEnable(m_CurClip != null && bindingInfos.Count > 0);
            if (EUtil.Button("Apply Prefix", Color.green))
            {
                _DoApplyPrefix(bindingInfos, m_Prefix);
            }
            EUtil.PopGUIEnable();
        }
        private void _GUI_ChangePath()
        {
            EditorWindow uaw      = (EditorWindow)EUtil.GetUnityAnimationWindow();
            object       uawstate = EUtil.GetUnityAnimationWindowState(uaw);

            m_CurClip = RCall.GetField("UnityEditorInternal.AnimationWindowState",
                                       "m_ActiveAnimationClip", uawstate) as AnimationClip;

            //1. collect the TrPaths from active curves
            List <EditorCurveBinding> bindingInfos = new List <EditorCurveBinding>();

            IList curves = (IList)RCall.GetProp("UnityEditorInternal.AnimationWindowState", "activeCurves", uawstate);

            if (curves.Count <= 0)
            {
                EditorGUILayout.LabelField("Please Select a Curve first...");
                return;
            }

            EditorCurveBinding theBinding   = (EditorCurveBinding)RCall.GetProp("UnityEditorInternal.AnimationWindowCurve", "binding", curves[0]);
            string             toChangePath = theBinding.path;

            IList allCurves = (IList)RCall.GetProp("UnityEditorInternal.AnimationWindowState", "allCurves", uawstate);

            foreach (var oneUAWCurve in allCurves)
            {
                EditorCurveBinding oneBinding = (EditorCurveBinding)RCall.GetProp("UnityEditorInternal.AnimationWindowCurve", "binding", oneUAWCurve);
                if (oneBinding.path == toChangePath)
                {
                    bindingInfos.Add(oneBinding);
                }
            }

            //2. display
            EditorGUILayout.LabelField("Affected curves:");
            m_scrollPos = EditorGUILayout.BeginScrollView(m_scrollPos, false, true, GUILayout.Height(200f));
            {
                foreach (var oneInfo in bindingInfos)
                {
                    EditorCurveBinding oneBinding = oneInfo;
                    GUILayout.BeginHorizontal();
                    {
                        EUtil.PushContentColor(Color.yellow);
                        GUILayout.Label(oneBinding.path);
                        EUtil.PopContentColor();
                        EUtil.PushContentColor(Color.green);
                        GUILayout.Label(oneBinding.propertyName);
                        EUtil.PopContentColor();
                    }
                    GUILayout.EndHorizontal();
                }
            }
            EditorGUILayout.EndScrollView();

            //3. apply prefix
            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("R", GUILayout.Width(20)))
            {
                GUIUtility.keyboardControl = 0;
                m_NewPath = toChangePath;
            }
            m_NewPath = EditorGUILayout.TextField("New Path:", m_NewPath);
            EditorGUILayout.EndHorizontal();

            EUtil.PushGUIEnable(m_CurClip != null && bindingInfos.Count > 0);
            if (EUtil.Button("Change Path!", Color.green))
            {
                _DoChangePath(bindingInfos, m_NewPath);
            }
            EUtil.PopGUIEnable();
        }