Wednesday, August 13, 2008


I've been working on the design a bit more. The top part of the diagram is an anatomical description of what objects in the advanced timeline should look like. Ideally I'd like all objects to support keyframeable properties, not just effects. This will require some changes to PiTiVi core -- in particular, all timeline objects will have to support getting/setting keyframes, which means internally they'll all have gst-controller objects. Personally, I think that's fine: one thing people overwhelmingly seem to want is to be able to directly control image opacity and audio volume.

One thing I'm not quite sure how to handle, though, are simple effects. You see, Edward's paper notes suggest that simple-effects (effects which only take one source as input) should appear in a small gutter above the other timeline objects within a given layer. This gutter would also be used for transitions. But this design leaves no room for over-laying keyframes, unless we allow simple-effects to expand to full height. But if we do that it will be difficult to distinguish beween simple effects and complex effects. So, perhaps *all* effects should simply be full-size objects , as in the above design. One thing I don't like about this, though, is that it's actually kinda hard to tell what's going on. Will videobox apply to just the image source directly below it, or the entire composition?

So, I came up with a different design. Move the properties down below the timeline, but keep them in sync with the timeline's scroll position. Now all objects can have as many properties as they want, and they can be kept completely separate from each other (or they could show as overlapping curves, I'm not yet sure which is best. The idea is that you select an object (in this image, the lighter colored simple effect is selected), and the property viewer displays its property graph. If you select multiple objects, one of two things could happen: it could show the intersection of the properties of all selected objects and let you set the same keyframe/values for all selected objects; or the property browser could display the properties of all selected objects individually. Ideally you'd want some combination of both, but I can't think of an elegant way to do that just yet.

Details: In either design, whenever you adjust a property, the viewer should show a preview of the keyframe after the effect has been applied.

Monday, August 11, 2008

Still thinking about the current problem of multiple selection draging. The only thing I've been able to work out so far is that there needs to be some separation between the event handling code and the widgets presented to the user. In other words, rather than doing Model/View-controller, there really should be separate Model/View/Controller objects. Goocanvas items are View-Controller objects: they represent data in the view, but they also handle user interaction. This is convenient when there's a one-to-one relationship. I wrote most of my code with this assumption in mind, so it's really easy to make any canvas item independently movable. Trying to move several items together poses a problem because each item will have an explicit pointer grab and receive all the pointer events. This is best summarized with the following diagram:

The alternative is to have some other object handle all the pointer events, and set the appropriate properties on the core objects:
I like this idea because it allows the selection to simply be the set of core objects on which the next command will take effect. It allows goocanvas and GTK to do all the event handling, however, it puts all of the logic for user interaction in one place: the signal handler attached to the root canvas item. Why is that bad? because not all PiTiVi core objects are alike, and not all have the quite the same interface. In particular, some objects have media-start/media-duration, while others don't. And if the media/start-media duration are not kept in sync with timeline start/duration, wierd things will happen. It would be great if they did, and this might be motivation to develop a consistent interface for all the PiTiVi core objects (i.e. abstract media-duration into media-offset).

Another way to get around this is to subclass the base UI timeline object and provide a handler which does the actual property setting. I don't really like this because it means that the current selection is a list of UI objects. This means the UI has to filter out the canvas items which are not directly selectable (because many items are actually groups of items).

Still another way of doing this might be to move the notion of selection out of the UI and into the back end.

In any case, the trimming handles on each source are a special case: we don't want to resize all the objects in the selection at the same time (do we?) My intuition tells me that users wouldn't care for that very much, because I wouldn't care for that very much. This isn't the end of the world: one simple solution would be to implement trimming handles as separate objects (as is currently done), and let them handle their own events. This way they won't propagate up to the root item, and therefore won't affect the current selection. And we can do this for any kind of UI element we don't want to become individually selectable, like, for example, objects representing keyframes on an effect item.

Wednesday, August 6, 2008


Things were plodding along fairly well until I tried to start working on multiple-selection-dragging . I got stuck, seriously stuck. I couldn't find a clean way to handle this. Things got even worse when I started thinking about how I would implement keyframes and editing markers. I decided to go back to the drawing board:
Basically, after taking a few days a few days to deal with personal matters, I started redesigning the implementation of the advanced UI from scratch. I haven't written a single line of code.

The inspiration that I hit upon recently is the idea of a Control Point, which is a generalized mapping between something the user can see and manipulate to an arbitrary property belonging to some object in the model. The idea is that for every property in PiTiVi core that you want to control, you have a control point to control it. In addition, when properties in the advanced UI change, the control points update their values as well. This way, objects in the UI are actually defined either as control points or as sets of control points. All the user interaction will be routed through a central Selection object, and then dispatched to all the selected control points. This supports everything from multi-selection dragging to handling undo/redo.

Where this idea goes wrong is when you have an object defined as a relationship between control points that is not one-to-one. For example, the relationship between the start/duration properties of a TimelineObject and the Start/End points of a ComplexTimelineObject is not one-to-one. If you adjust the start or end point of the object independently, both the start and the duration values change. If you adjust the Start/End points together, only the Start property changes. This is a consequence of the mathematical relationship between the out-point of the object and the source's start/duration. I'm not quite sure where to go from here, but I think the best course of action is to provide a layer of indirection between the control points and properties. If you have a proxy object which has an in-point and an out-point, which in turn computes start/duration, for example, all the UI Selection object needs to care about are the In/Out control points.