public DraggedKeyframe(int index, KeyFrame original)
 {
     this.index = index;
     this.original = original;
 }
        /// <summary>
        /// Initializes the drop down window by creating the necessary GUI. Must be called after construction and before
        /// use.
        /// </summary>
        /// <param name="keyFrame">Keyframe whose properties to edit.</param>
        /// <param name="updateCallback">Callback triggered when event values change.</param>
        /// <param name="closeCallback">Callback triggered just before the window closes.</param>
        internal void Initialize(KeyFrame keyFrame, Action<KeyFrame> updateCallback, Action<bool> closeCallback)
        {
            GUIFloatField timeField = new GUIFloatField(new LocEdString("Time"), 40, "");
            timeField.Value = keyFrame.time;
            timeField.OnChanged += x => { keyFrame.time = x; changesMade = true; updateCallback(keyFrame); };

            GUIFloatField valueField = new GUIFloatField(new LocEdString("Value"), 40, "");
            valueField.Value = keyFrame.value;
            valueField.OnChanged += x => { keyFrame.value = x; changesMade = true; updateCallback(keyFrame); };

            GUILayoutY vertLayout = GUI.AddLayoutY();

            vertLayout.AddFlexibleSpace();
            GUILayoutX horzLayout = vertLayout.AddLayoutX();
            horzLayout.AddFlexibleSpace();
            GUILayout contentLayout = horzLayout.AddLayoutY();
            GUILayout timeLayout = contentLayout.AddLayoutX();
            timeLayout.AddSpace(5);
            timeLayout.AddElement(timeField);
            timeLayout.AddFlexibleSpace();
            GUILayout componentLayout = contentLayout.AddLayoutX();
            componentLayout.AddSpace(5);
            componentLayout.AddElement(valueField);
            componentLayout.AddFlexibleSpace();
            horzLayout.AddFlexibleSpace();
            vertLayout.AddFlexibleSpace();

            this.closeCallback = closeCallback;
        }
 /// <summary>
 /// Creates a new animation curve.
 /// </summary>
 /// <param name="keyFrames">Keyframes to initialize the curve with.</param>
 public AnimationCurve(KeyFrame[] keyFrames)
 {
     Internal_Create(this, keyFrames);
 }
 private static extern void Internal_SetKeyFrames(IntPtr thisPtr, KeyFrame[] keyframes);
 private static extern void Internal_Create(AnimationCurve instance, KeyFrame[] keyframes);
        /// <summary>
        /// Returns the position of the tangent, in element's pixel space.
        /// </summary>
        /// <param name="keyFrame">Keyframe that the tangent belongs to.</param>
        /// <param name="type">Which tangent to retrieve the position for.</param>
        /// <returns>Position of the tangent, relative to the this GUI element's origin, in pixels.</returns>
        private Vector2I GetTangentPosition(KeyFrame keyFrame, TangentType type)
        {
            Vector2I position = CurveToPixelSpace(new Vector2(keyFrame.time, keyFrame.value));

            Vector2 normal;
            if (type == TangentType.In)
                normal = -EdAnimationCurve.TangentToNormal(keyFrame.inTangent);
            else
                normal = EdAnimationCurve.TangentToNormal(keyFrame.outTangent);

            // X/Y ranges aren't scaled 1:1, adjust normal accordingly
            normal.x /= GetRange();
            normal.y /= yRange;
            normal = Vector2.Normalize(normal);

            // Convert normal (in percentage) to pixel values
            Vector2I offset = new Vector2I((int)(normal.x * TANGENT_LINE_DISTANCE),
                    (int)(-normal.y * TANGENT_LINE_DISTANCE));

            return position + offset;
        }
        /// <summary>
        /// Draws zero, one or two tangents for the specified keyframe. Whether tangents are drawn depends on the provided
        /// mode.
        /// </summary>
        /// <param name="keyFrame">Keyframe to draw the tangents for.</param>
        /// <param name="tangentMode">Type of tangents in the keyframe.</param>
        private void DrawTangents(KeyFrame keyFrame, TangentMode tangentMode)
        {
            Vector2I keyframeCoords = CurveToPixelSpace(new Vector2(keyFrame.time, keyFrame.value));

            if (IsTangentDisplayed(tangentMode, TangentType.In))
            {
                Vector2I tangentCoords = GetTangentPosition(keyFrame, TangentType.In);

                canvas.DrawLine(keyframeCoords, tangentCoords, Color.LightGray);
                DrawDiamond(tangentCoords, 2, Color.Green, Color.Black);
            }

            if (IsTangentDisplayed(tangentMode, TangentType.Out))
            {
                Vector2I tangentCoords = GetTangentPosition(keyFrame, TangentType.Out);

                canvas.DrawLine(keyframeCoords, tangentCoords, Color.LightGray);
                DrawDiamond(tangentCoords, 2, Color.Green, Color.Black);
            }
        }