Skip to content

WinForms Timeline Renderers, Controls, and Manipulators

Gary edited this page Aug 27, 2014 · 1 revision

Table of Contents

These classes are responsible for drawing timelines in a control and providing extra capabilities. These classes use Direct2D to draw and work with timelines. These are for Windows® Forms, and reside in the Sce.Atf.Controls.Timelines.Direct2D namespace and Atf.Gui.WinForms assembly.

There are both Direct2D and GDI versions of all the classes. You should use the much faster Direct2D versions, because the GDI versions are obsolete.

Timeline Renderers

The timeline renderers draw timeline objects on a canvas provided by a timeline control.

D2dTimelineRenderer Class

The abstract base class D2dTimelineRenderer renders the timeline and objects in it using Direct2D. It works with a timeline control, such as D2dTimelineControl.

D2dTimelineRenderer provides most of the timeline rendering capabilities:

  • Init() method to initialize the renderer.
  • Properties for various graphics objects used in rendering.
  • Dispose() method for disposing of graphics objects.
  • Numerous properties to configure the rendering, such as TrackIndent for track indentation and HeaderWidth for group and track header width.
  • Draw() and Print() methods to draw the timeline to the display.
  • Various private methods to draw timeline parts, such as sub-timelines, markers, groups, ghosts for moving and resizing objects, and so on.
  • Pick() methods for getting a list of timeline objects hit in a rectangle.
  • GetBounds() methods to find the bounds of timeline objects, such as intervals, keys, and markers.
  • Abstract methods to draw particular objects, such as groups, tracks, and keys.
  • Context class with useful information for laying out and drawing timeline elements, such as the D2dTimelineRenderer and D2dGraphics objects. This context is used as a parameter in several methods, such as the Draw() methods.

D2dDefaultTimelineRenderer Class

Because D2dTimelineRenderer is abstract, you must derive a class from it to produce an actual renderer, which is D2dDefaultTimelineRenderer's role. A timeline application can use D2dDefaultTimelineRenderer or a class like it.

D2dDefaultTimelineRenderer has an Init() method to initialize the graphic objects it uses to draw timeline objects.

D2dDefaultTimelineRenderer also has properties to customize rendering, such as TrackHeight for the track height, relative to a unit of time.

D2dDefaultTimelineRenderer overrides the abstract Draw() methods in D2dTimelineRenderer to draw the following objects:

  • Group
  • Track
  • Interval
  • Key
  • Marker

Timeline Controls

Timeline controls display the rendered timeline. There are two versions: D2dTimelineControl for Direct2D and TimelineControl for GDI. As already noted, you should use D2dTimelineControl.

D2dTimelineControl derives from CanvasControl, a control for viewing and editing a 2D bounded canvas. The constructor with the most arguments is:

public D2dTimelineControl(
    ITimelineDocument timelineDocument,
    D2dTimelineRenderer timelineRenderer,
    TimelineConstraints timelineConstraints,
    bool createDefaultManipulators)

All constructors require the ITimelineDocument argument. If D2dTimelineRenderer or TimelineConstraints are not supplied, default objects are constructed for them. The parameter createDefaultManipulators indicates whether default manipulators should be constructed for the control. For details about these manipulators, see Timeline Manipulators.

D2dTimelineControl provides the Direct2D graphics device used for drawing in its D2dGraphics property. This value is used whenever drawing occurs.

D2dTimelineControl has a set of Create() methods to create these objects using an ITimelineObjectCreator:

  • Group
  • Track
  • Interval
  • Key
  • Marker
It also has enumerator properties to get all instances of objects: AllEvents, AllMarkers, AllTracks, and AllGroups.

The control also handles events, such as for mouse actions and painting.

Timeline Manipulators

Manipulators allow you to manipulate timeline objects in a timeline control. These function somewhat like control adapters, in that they add capabilities to a control. However, they do not derive from ControlAdapter and the control they operate on, D2dTimelineControl, is not an AdaptableControl.

The manipulators all take a D2dTimelineControl parameter to attach them to that control, as for D2dMoveManipulator:

public D2dMoveManipulator(D2dTimelineControl owner)

This manipulator is created this way, for example, where m_timelineControl holds a D2dTimelineControl:

D2dMoveManipulator moveManipulator = new D2dMoveManipulator(m_timelineControl);

This table describes the Direct2D manipulators:

Manipulator Description
D2dMoveManipulator A timeline manipulator for moving IEvent objects, such as markers, keys, and intervals.
D2dScaleManipulator Creates the scale manipulator, a horizontal bar on top of the scale bar. It has handles at each end, bracketing the selection set. It has two distinct modes:
  1. Individual interval scaling occurs when the left or right border of an interval is scaled. In this case, the entire selection of intervals is scaled "in place". That is, their starting locations do not change. Only intervals are affected.
  2. If the handles on the scaling manipulator are dragged, the portion of the timeline that is bracketed by the first selected object to the last selected object is scaled in time.
Everything selected is scaled–keys, markers, and intervals.
D2dScrubberManipulator Creates the scrubber manipulator, a vertical bar that can slide left and right by grabbing the handle on top.
D2dSelectionManipulator A timeline manipulator for implementing the selection logic. It should probably be attached first to the timeline control. The attachment is permanent and there must be one timeline control per ITimelineDocument.
D2dSnapManipulator A timeline manipulator intended to be used by other manipulators to allow for snapping selected objects to non-selected events and give a visual indication of this.
D2dSplitManipulator A timeline manipulator for splitting intervals into two. When hovering the mouse over an interval, if the user holds down a modifier key (Alt by default), the cursor changes to indicate where a split will take place. On the MouseDown event, the interval is split.

The order in which these manipulators are attached to the D2dTimelineControl matters. The order here determines the order of receiving Paint events and is the reverse order of receiving picking events. For example, a custom control that is drawn on top of everything else and that can be clicked on should come last in this list, so that it is drawn last and is picked first.

This is the recommended order in which manipulators should be constructed.

  1. D2dSelectionManipulator
  2. D2dMoveManipulator
  3. D2dScaleManipulator
  4. D2dSplitManipulator
  5. D2dSnapManipulator
  6. D2dScrubberManipulator

Putting It All Together: Using the Timeline Classes

Follow these steps to create a timeline with these classes.

  1. Construct the D2dDefaultTimelineRenderer. Its constructor takes no parameters, so it is easy:
    m_renderer = new D2dDefaultTimelineRenderer();
  2. Create the D2dTimelineControl, as in this statement:
    m_timelineControl = new D2dTimelineControl(null, m_renderer, new TimelineConstraints(), false);
    Recall that the first argument is an ITimelineDocument, which can be null. The second argument is a D2dTimelineRenderer; if null, a new D2dDefaultTimelineRenderer is constructed and used. The third argument is a TimelineConstraints, which can be constructed in-line. For more information, see TimelineConstraints Class.
  3. Set the D2dTimelineControl's TimelineDocument property to the ITimelineDocument, if there is one.
  4. Attach manipulators to the control by constructing them with the D2dTimelineControl, as in:
    D2dMoveManipulator moveManipulator = new D2dMoveManipulator(m_timelineControl);
    Construct manipulators in the recommended order. For more details, see Timeline Manipulators.
  5. Initialize the D2dDefaultTimelineRenderer with the D2dGraphics object from the D2dTimelineControl, as in this code. Here m_renderer contains the renderer, document is the ITimelineDocument, which has a TimelineControl property containing the timeline control:
    m_renderer.Init(document.TimelineControl.D2dGraphics);
    The D2dGraphics object is obtained from the D2dGraphics property of the control.

The TimelineEditor component and TimelineDocument class of the ATF Timeline Editor Sample perform these steps. For more information on how these controls are used, see Timeline Editor Programming Discussion.

Obsolete Classes

The classes discussed here are the Direct2D versions. There is an older set of classes with the same kind of functionality that use GDI drawing instead. For example, D2dTimelineRenderer is the Direct2D version of the GDI TimelineRenderer. As elsewhere, the Direct2D version of the classes have the prefix "D2d".

The GDI classes are obsolete. You should use the much faster classes in the Sce.Atf.Controls.Timelines.Direct2D namespace.

Topics in this section

Clone this wiki locally