Nevron Open Vision Documentation
The Visual Tree

 
Visual Trees Overview

In the DOM the painting and hit-testing are performed by different display visitors that derive from the base NDisplayVisitor class. Display visitors are designed to traverse the DOM visual tree. The DOM visual tree consists of elements that derive from the NVisual abstract class, that derives from the NElement class. The following image illustrates the visual tree inside a DOM hierarchy:

figure 1. The Visual Tree

From the image we can clearly see that nodes that do not derive from NVisual (elements D and C) are excluded from the visual tree (i.e. the parent visual of H, I and E is B). Also evident from the image is that the visual tree may span across the aggregated subtree of the root visual A (see Nodes for more information) - i.e. G resides in the property dimension of A, but as far as the visual tree is concerned, its parent visual is A and A visual children are B, G and F.

Each time a display visitor visits a visual, it asks it to provide its current set of display children by calling the NVisual-AccumulateDisplayChildren method. This means that the visual tree is dynamic (for example: it is up to A to decide whether to include B, G and F in its display children list).

The visual tree is always traversed in a depth first order. Furthermore display visitors distinguish between pre-visiting and post-visiting. The visual pre-visiting is performed prior to the traversal of its subtree. The visual post-visiting is performed after the traversal of its subtree.

Paint visitors traverse the current visual display children in forward order (i.e the first child is visited first). Thus the visual tree from figure 1 is painted in this order: A, B, H, E, I, G, F. If we apply the pre and post visiting steps we get the following painting sequence:

A - pre
B - pre
H - pre, post
E - pre, post
I - pre, post
B - post
G - pre, post
F - pre, post
A - post

Hit-test visitors traverse the current visual display children in reverse order (i.e. the last child is visited first). Thus the visual tree from figure 1 is hit-tested in this order: A, F, G, B, I, E, H. If we apply the pre and post visiting steps we get the following hit-testing sequence:

A - pre,
F - pre, post,
G - pre, post
B - pre,
I - pre, post
E - pre, post
H - pre, post
B - post,
A - post

Visuals typically paint themselves on pre paint visiting (painters algorithm) and hit test themselves on post hit test visiting.

The common features related to both painting and hit testing include:

These features are a joint responsibility of the visuals and the NDisplayVisitor class, from which both paint and hit test visitors derive. The rest of this topic discusses these features.

When we talk about transformations and coordinates in general, it is very important to remember that the DOM unit of measurement related to painting and hit-testing coordinates is the DIP (device independent pixel). One DIP is 1/96 of the inch. This means that the DOM is resolution independent (is measured in actual length and not in pixels).
Transform Management

The NVisual class provides several virtual methods that descendant classes override to provide a transformation for the visual. The visual transformation is a 2D affine matrix represented by the Nevron.Graphics.NMatrix structure. The visual transformation is returned by the NVisual-GetTransform method. If the currently returned transformation is different than the identity matrix, the NVisual-CanTransform method returns true.

The visual transformation represents the transformation of local-to-parent coordinates. This means that visuals, which can provide a transformation, have a local coordinate system. In NOV coordinate systems are having the orientation of the screen coordinate system, in which X coordinates increase to the right, and Y coordinates increase to the bottom of the screen. The presence of a local coordinate system allows for painting, clipping and hit-test operations to be performed in local coordinates. To better illustrate coordinate systems, consider a NOV UI window, containing two embedded widgets like shown in the following image:

figure 2. Coordinate Systems.

As far as the widgets are concerned (or any other visuals) they are painted and hit-tested in local coordinates. To transform a point from visual local coordinates to parent-visual coordinates you can use the NVisual-LocalToParent method. Reversely to transform a point in from parent visual coordinates to local visual coordinates you can use the NVisual-ParentToLocal method. Similarly you can use the NVisual-LocalToAncestor and NVisual-AncestorToLocal methods to transform local coordinates to any ancestor coordinate system and vice-versa.

To transform between local and screen coordinates you can use the NVisual-TryLocalToScreen and NVisual-TryScreenToLocal methods. For certain visuals hierarchy, the screen coordinate system may not be available. This is the case of all visual trees that are constructed and rendered off-screen (for example for the purpose of printing). That is why the methods that allow you to transform between local and screen coordinates may not always succeed.

Each display visitor manages a transformation stack, which is modified by its PushTransform and PopTransform methods. The current transformation accumulated by a display visitor is returned by the NDisplayVisitor-GetTransform() method. The PushTransform method pushes the current transform in the stack and makes the new transformation equal to the matrix multiplication of the pushed transform and the previous current transform. The PopTransform method reverts the current transformation to the previously pushed one.

When a display visitor enters the visual subtree of a visual, whose NVisual-CanTransform method returns true, it automatically calls its PushTransform method, by passing as argument the transformation returned by the NVisual-GetTransform() method. When a display visitor leaves the visual subtree of a visual, whose NVisual-CanTransform method returns true, it automatically calls its PopTransform method.

For window painting and hit testing purposes the respective visitors are launched from the window itself, meaning that the NDisplayVisitor-GetTransform() method will return the current transformation from local to window coordinates. Display visitors however may be launched from arbitrary visuals. The visual from which a display visitor is launched is called the scene visual, and its coordinate system is the scene coordinate system for the display visitor. Thus the NDisplayVisitor-GetTransform() method returns the current local to scene transformation.

Clip Management

The NVisual class provides several virtual methods that descendant classes override to provide clip regions for the visual. Clip regions are represented by the Nevron.Graphics.NRegion class, which represents an arbitrary closed area in 2D space. Each visual can have two clip regions:  

  1. Subtree clip region.

    The visual subtree clipping region is returned by the NVisual-GetClip method. If the currently returned subtree region is valid, the NVisual-CanClip method returns true.

  2. Children clip region.
    The visual children clipping region is returned by the NVisual-GetChildrenClip method. If the currently returned children clip region is valid, the NVisual-CanClipChildren method returns true.

Each display visitor manages a clip stack, which is modified by its PushClip and PopClip methods. The current clip region accumulated by a display visitor is available in local and scene coordinates. The NDisplayVisitor-GetLocalClip() method returns the clipping region in local coordinates. The NDisplayVisitor-GetSceneClip() returns the clipping region in scene coordinates.

The PushClip method pushes the current clip region in the stack and makes the new clip region equal to the intersection of the pushed clip region and the previous clip region. The PopClip method reverts the current clip region to the previously pushed one. This means that the painting and hit-testing are always performed in an ever narrowing areas.

When a display visitor enters the visual subtree of a visual, whose NVisual-CanClip method returns true, it automatically calls its PushClip method, by passing as argument the region returned by the NVisual-GetClip method. When a display visitor leaves the visual subtree of a visual, whose NVisual-CanClip method returns true, it automatically calls its PopClip method.

When a display visitor starts to visit the children provided by a visual, whose NVisual-CanClipChildren method returns true, it automatically calls its PushClip method, by passing as argument the region returned by the NVisual-GetChildrenClip method. When a display visitor has ended visiting the children of a visual, whose NVisual-CanClipChildren method returns true, it automatically calls its PopClip method.

See Also
Send Feedback