public static void DrawAnimationData(SerializedProperty property, UIAnimationHelper helper, bool showProgress = true)
        {
            var spPreset = property.FindPropertyRelative("m_Preset");

            EditorGUI.BeginDisabledGroup(spPreset.objectReferenceValue && !enableEdit);

            var spAnimationData = spPreset.objectReferenceValue
                                ? new SerializedObject(spPreset.objectReferenceValue).FindProperty("m_AnimationData")
                                : property;

            var spDatas = spAnimationData.FindPropertyRelative("m_TweenDatas");

            // Available type.
            using (new EditorGUILayout.VerticalScope("helpbox"))
            {
                DrawAvailableTypes(EditorGUILayout.GetControlRect(false, 20), new GUIContent("Type"), property);
                GUILayout.Space(-2);
            }

            var tag = (State)property.FindPropertyRelative("m_State").intValue;

            // Animation datas.
            for (int i = 0; i < spDatas.arraySize; i++)
            {
                var spData = spDatas.GetArrayElementAtIndex(i);
                var rate   = helper != null ? helper.m_Rates[spData.FindPropertyRelative("propertyType").intValue] : 0;
                DrawTweenData(spData, helper, Mathf.Abs(Mathf.Repeat(rate + 1, 2) - 1), tag, showProgress);
            }
            EditorGUI.EndDisabledGroup();

            spDatas.serializedObject.ApplyModifiedProperties();
        }
        public static void DrawTweenData(SerializedProperty property, UIAnimationHelper helper, float rate, State tag, bool showProgress = true)
        {
            var labelwidth = EditorGUIUtility.labelWidth;

            // Header
            PropertyType type    = (PropertyType)property.FindPropertyRelative("propertyType").intValue;
            var          rHeader = GUILayoutUtility.GetRect(18, 18);

            GUI.Label(rHeader, new GUIContent(type.ToString(), icons[type]), styleHeader);

            // Progress
            if (showProgress)
            {
                Rect rProgress = new Rect(rHeader.x + 80, rHeader.y + 3, rHeader.width - 200, rHeader.height - 6);
                GUI.Label(rProgress, GUIContent.none, "ProgressBarBack");
                rProgress.width *= rate;
                GUI.Label(rProgress, GUIContent.none, "ProgressBarBar");
            }

            // LoopMode
            bool onceOnly = tag == State.Show || tag == State.Hide || tag == State.Click;
            var  spLoop   = property.FindPropertyRelative("loop");

            using (new EditorGUI.DisabledGroupScope(onceOnly))
            {
                EditorGUIUtility.labelWidth = 35;
                Rect r = new Rect(rHeader.x + rHeader.width - 115, rHeader.y + 1, 110, rHeader.height);
                if (onceOnly)
                {
                    EditorGUI.EnumPopup(r, spLoop.displayName, UITweenData.LoopMode.Once);
                }
                else
                {
                    EditorGUI.PropertyField(r, spLoop);
                }
            }

            // Inner
            using (new EditorGUILayout.HorizontalScope(styleInner))
            {
                using (new EditorGUILayout.VerticalScope())
                {
                    // Movement
                    DrawMovement(EditorGUILayout.GetControlRect(), property, helper);

                    // Time
                    DrawTime(EditorGUILayout.GetControlRect(), property);
                }

                // Curve
                float size = EditorGUIUtility.singleLineHeight * 2 + 2;
                DrawCurve(EditorGUILayout.GetControlRect(false, size, GUILayout.MaxWidth(size + 12)), property.FindPropertyRelative("curve"));
            }
            EditorGUIUtility.labelWidth = labelwidth;
        }
        /// <summary>
        /// Draw movement property.
        /// When relative was changed, switch the value.
        /// </summary>
        static void DrawMovement(Rect r, SerializedProperty spData, UIAnimationHelper helper)
        {
            var spType     = spData.FindPropertyRelative("propertyType");
            var spRelative = spData.FindPropertyRelative("relative");
            var spMovement = spData.FindPropertyRelative("movement");

            // Relative/Absolute toggle.
            // When it was changed, switch the value.
            Rect   rRelative = new Rect(r.x, r.y, 52, r.height);
            string label     = spRelative.boolValue ? "Relative" : "Absolute";

            if (GUI.Toggle(rRelative, spRelative.boolValue, label, EditorStyles.miniButton) != spRelative.boolValue)
            {
                spRelative.boolValue = !spRelative.boolValue;

                switch ((PropertyType)spType.intValue)
                {
                case PropertyType.Position:
                    spMovement.vector3Value += (spRelative.boolValue ? -1 : 1) * helper.position;
                    break;

                case PropertyType.Rotation:
                    spMovement.vector3Value += (spRelative.boolValue ? -1 : 1) * helper.rotation;
                    break;

                case PropertyType.Scale:
                    spMovement.vector3Value += (spRelative.boolValue ? -1 : 1) * helper.scale;
                    break;

                case PropertyType.Size:
                    spMovement.vector3Value += (spRelative.boolValue ? -1 : 1) * helper.size;
                    break;

                case PropertyType.Alpha:
                    spMovement.vector3Value += (spRelative.boolValue ? -1 : 1) * new Vector3(helper.alpha, 0);
                    break;

                case PropertyType.Custom:
                    break;
                }
            }

            // Movement property.
            var rField = new Rect(r.x + 52 + 2, r.y, r.width - 52 - 2, r.height);

            // Alpha
            if ((PropertyType)spType.intValue == PropertyType.Alpha)
            {
                EditorGUIUtility.labelWidth = 35;
                EditorGUI.PropertyField(rField, spMovement.FindPropertyRelative("x"), new GUIContent("Alpha"));
            }
            // Vector2/Vector3
            else
            {
                int split = (PropertyType)spType.intValue == PropertyType.Size ? 2 : 3;

                EditorGUIUtility.labelWidth = 11;
                rField.width /= split;

                EditorGUI.PropertyField(rField, spMovement.FindPropertyRelative("x"));
                rField.x += rField.width;
                EditorGUI.PropertyField(rField, spMovement.FindPropertyRelative("y"));
                rField.x += rField.width;
                if (split == 3)
                {
                    EditorGUI.PropertyField(rField, spMovement.FindPropertyRelative("z"));
                }
            }
        }