Work is progressing on the keyframes branch. You can now save, load, and split 
track objects and the keyframe data will be preserved. What remains to be done 
before merging is to add undo / redo support to keyframes. Other improvements 
can then be made incrementally after the merging.

I have had a look at the timeline_undo.py code, and so I get the general idea 
of 
what is supposed to happen, but i'm still not sure what the best way forward 
is. 
The existing code is organized around TimelineObjects. Interpolators and their 
child Keyframes are only accessible at the TrackObject level.

I figure that I need to add at least the following classes:

KeyframeAddedAction(UndoableAction)
KeyframeRemovedAction(UndoableAction)
KeyframeMovedAction(UndoableAction)

These get posted to the UndoableActionLog by the UI after the user adds, 
removes, or moves a keyframe. This leaves the question of how to observe 
Keyframe property changes.

My thought is to extend the undo class hierarchy all the way down to the 
Keyframe, or at least the Interpolator level. This would involve adding the 
following classes

-TrackObjectPropertyChangeTracker   ; watches individual track object
-InterpolatorPropertyChangeTracker  ; watches individual interpolator
-TimelineObjectLogObserver          ; manages list of
                                       TrackObjectProertyChangeTrackers
-TrackObjectLogObserver             ; manages list of
                                       InterpolatorPropertyChangeTrackers

Note that we don't really need a KeyframePropertyChangeTracker, or 
InterpolatorLogObserver, because the interpolator emits a signal whenever a 
keyframe moves.

The question on my mind is how to nest the hierarchy. My guess is that the 
*LogObservers should nest into each other as shown below. I'm basing this on 
the 
fact that it's the Application, not the Timeline, which holds the 
TimelineLogObserver.

I'm going to take a bit of an inductive leap here and speculate that the 
*LogObserver for the next level down should be a child of the 
*PropertyChangeTracker for the level above it. So, when the 
TrackObjectLogObserver records a change in an Interpolator, it can emit a 
signal 
that the parent TrackObjectPropertyChangeTracker can handle and forward up to 
the TimelineObjectLogObserver, and so on.

TimelineLogObserver
   |_TimelineObjectPropertyChangeTrackers
     |_TimelineObjectLogObserver
       |_TrackObjectPropertyChangeTrackers
         |_TrackObjectLogObservers
           |_InterpolatorPropertyChangeTrackers

A similar approach would be to put the associated *LogObserver into the objects 
they are associated with, like this:

Application
  |_Timeline
    |_TimelineLogObserver
    | |_TimelineObjectPropertyChangeTrackers
    |_TimelineObjects
      |_TimelineObjectLogObserver
      | |_TrackObjectPropertyChangeTrackers
      |_TrackObjects
        |_TrackObjectLogObserver
        | |_InterpolatorPropertyChangeTrackers
        |_Interpolators

This approach basically means coupling undo / redo support more tightly with 
the 
PiTiVi core objects, with each object responsible for logging observations from 
the child objects one level below. Using this approach it might also be a good 
idea to have each object create it's own *PropertyChangeTracker so that 
subclasses can have some control over what is observed (for example, adding or 
removing undoable properties).

A simpler approach would be to expose Interpolators / Keyframes as a 
TimelineObject-level API, and just do everything from inside 
TimelineObjectPropertyChange tracker, but I'm not really that fond of this idea 
since it violates the TimelineObject abstraction, and adds another code path 
for 
manipulating keyframes.

------------------------------------------------------------------------------
_______________________________________________
Pitivi-pitivi mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/pitivi-pitivi

Reply via email to