private void OnDragCompleted(object sender, DragCompletedEventArgs e)
 {
     XCenterThumb.Cursor = Cursors.Arrow;
     if (m_MoveDirection == MoveDirection.Vertical)
     {
         App.Current.UndoRedoStack.Add(_addOrUpdateKeyframeCommand);
     }
     else if (m_MoveDirection == MoveDirection.Horizontal)
     {
         App.Current.UndoRedoStack.Add(_moveKeyframeCommand);
     }
     _addOrUpdateKeyframeCommand = null;
     _moveKeyframeCommand        = null;
     m_CE.RebuildCurrentCurves();
 }
        private void OnDragStart(object sender, DragStartedEventArgs e)
        {
            XCenterThumb.Cursor = Cursors.Cross;
            m_MoveDirection     = MoveDirection.Undecided;
            if (Keyboard.Modifiers != ModifierKeys.Shift)
            {
                var alreadySelected = CurveEditor._SelectionHandler.SelectedElements.Count == 1 &&
                                      Equals(CurveEditor._SelectionHandler.SelectedElements.First(), this);

                if (!alreadySelected)
                {
                    CurveEditor._SelectionHandler.Clear();
                }
            }
            CurveEditor._SelectionHandler.AddElement(this);
            _addOrUpdateKeyframeCommand = new AddOrUpdateKeyframeCommand(U, m_vdef, Curve);
            _moveKeyframeCommand        = new MoveKeyframeCommand(U, U, Curve);
        }
        public override void PasteKeyframes()
        {
            var addedNewCurves = false;

            List <ICommand> pasteKeyframeCommands   = new List <ICommand>();
            var             curvesWithSelectedTimes = getSelectedOrAllVDefinitions();

            var parameterNamesWithKeys = new Dictionary <String, List <Keyframe> >();

            try
            {
                parameterNamesWithKeys =
                    JsonConvert.DeserializeObject <Dictionary <String, List <Keyframe> > >(
                        Clipboard.GetText());
            }
            catch (Exception e)
            {
                Logger.Warn("Inserting keyframes failed: {0}", e.Message);
                return;
            }

            _updatingCurveEnabled = false;  // prevent update triggered by Curve.Move

            // Compute start and end times
            var minTime = double.PositiveInfinity;
            var maxTime = double.NegativeInfinity;

            foreach (var keyframe in parameterNamesWithKeys.Select(inputNameAndKeys => inputNameAndKeys.Value)
                     .SelectMany(keyframes => keyframes))
            {
                minTime = Math.Min(minTime, keyframe.Time);
                maxTime = Math.Max(maxTime, keyframe.Time);
            }

            // Collect matching curves
            var curvesWithMatchingInputs = new List <ICurve>();

            foreach (var inputNameAndKeys in parameterNamesWithKeys)
            {
                var inputName = inputNameAndKeys.Key;
                var keys      = inputNameAndKeys.Value;

                foreach (var input in curveInputs)
                {
                    if (input.Name != inputName)
                    {
                        continue;
                    }

                    var curve = curvesByInput[input];
                    curvesWithMatchingInputs.Add(curve);
                }
            }

            var curveMapping = new  List <Tuple <ICurve, List <Tuple <double, VDefinition> > > >();

            if (curvesWithMatchingInputs.Count == 0)
            {
                // Check if non-animated inputs exists.
                var parametersToAnimate = parameterNamesWithKeys.Keys.ToList();

                foreach (var se in m_ObservedOperatorWidgets)
                {
                    var opWidget = se as OperatorWidget;
                    if (opWidget == null)
                    {
                        continue;
                    }

                    foreach (var input in opWidget.Operator.Inputs)
                    {
                        if (parametersToAnimate.IndexOf(input.Name) == -1)
                        {
                            continue;
                        }

                        // Skip if already connected
                        if (input.Connections.Count > 0)
                        {
                            continue;
                        }

                        // Animate parameter
                        var addAnimiationCommand = new SetupAnimationCommand(input, App.Current.Model.GlobalTime);
                        App.Current.UndoRedoStack.AddAndExecute(addAnimiationCommand);

                        // Add to list of curves
                        var animationOpPart = Animation.GetRegardingAnimationOpPart(input);
                        var animationCurve  = animationOpPart.Func as ICurve;
                        curvesByInput[input] = animationCurve;
                        curveInputs.Add(input);
                        parametersToAnimate.Remove(input.Name);
                        addedNewCurves = true;
                    }
                }
            }

            // Insert gap to all animated parameters
            foreach (var curve in curvesByInput.Values)
            {
                var points = curve.GetPoints();
                points.Sort((a, b) => a.Key > b.Key ? -1:1);        // If moving unsorted, later keyframes could be overwritten.

                foreach (var timeWithKey in points)
                {
                    var time = timeWithKey.Key;
                    if (time > App.Current.Model.GlobalTime)
                    {
                        var c = new MoveKeyframeCommand(time, time + maxTime - minTime, curve);
                        pasteKeyframeCommands.Add(c);
                    }
                }
            }

            foreach (var inputNameAndKeys in parameterNamesWithKeys)
            {
                var inputName = inputNameAndKeys.Key;
                var keyframes = inputNameAndKeys.Value;

                foreach (var input in curveInputs)
                {
                    if (input.Name != inputName)
                    {
                        continue;
                    }

                    var curve = curvesByInput[input];

                    foreach (var keyframe in keyframes)
                    {
                        pasteKeyframeCommands.Add(new AddOrUpdateKeyframeCommand(keyframe.Time - minTime + App.Current.Model.GlobalTime, keyframe.VDefinition, curve));
                    }
                }
            }

            var macroCommand = new MacroCommand("Paste Keyframes", pasteKeyframeCommands);

            App.Current.UndoRedoStack.AddAndExecute(macroCommand);
            _updatingCurveEnabled = true;
            if (addedNewCurves)
            {
                ShowCurvesForSelectedOperators();
            }
            else
            {
                RebuildCurrentCurves();
            }
        }