Navigation:  Image Viewer Architecture > The Scene Graph >

Control Graphics

Previous pageReturn to chapter overviewNext page

It’s usually not sufficient to simply overlay vector graphics or text on an image.  Often times, you want to interact with them in some way, such as selecting them with the mouse, resizing them, moving them, and so on.  In the introduction to the scene graph, we saw an example of how support for user interaction was added to a plain RectanglePrimitive just by having the non-interactive primitive be a child of a BoundableStretchControlGraphic, and having that graphic, in turn, be a child of a BoundableResizeControlGraphic.  In a previous version of the framework, there were monolithic InteractiveGraphics which encapsulated all the logic and code behind making the underlying shape user-interactive.  These classes have now been replaced by modular IControlGraphics, each of which only knows how to manipulate a certain class of graphic in a specific manner and nothing else.  It is the tool writer's responsibility to assemble the modules together with an appropriate subject graphic such that it is controllable by the end user in the desired manner.

So, what does this mean? Instead of having a large inheritance hierarchy of graphics, where each defines it's own unique way in which a user can control it, we have a number of small graphic classes that only add a very specific means of control to another graphic – a design you may recognize as the Decorator pattern.  We won't go into the details here, but the Decorator pattern is used when you need to systematically add new functionality to an existing object without modifying the object itself.  In our Scene Graph example, the BoundableResizeControlGraphic and BoundableStretchControl graphic are decorators in that they each add a different way to resize the underlying rectangle primitive.  Generally, in the CC Framework, each IControlGraphic is actually a CompositeGraphic, and each directly owns either another IControlGraphic or the actual subject graphic (a primitive in this case) that is ultimately being controlled.  The sequence of control graphics controlling a particular subject graphic is referred to as the subject graphic's control chain (yet another common design pattern – Chain of Responsibility).

 

Since the entire purpose of control graphics is to add user-interactivity to the scene graph, all control graphics implement ICursorTokenProvider, IMouseButtonHandler, and IExportedActionsProvider. The order of control graphics in the control chain is very important because it ultimately determines which control graphics have priority when handling mouse input.  Any control graphic can also define actions that could be shown in a context menu – but the context menu will only be shown if a control graphic higher up in the control chain actually creates the context menu action model for display by implementing IContextMenuProvider.

 

As mentioned previously, each type of control graphic will typically only act on a certain class of subject graphic (normally primitives).  For example, the TextEditControlGraphic only operates on text graphics, since editing a text value wouldn't make sense otherwise.  Similarly, the LineSegmentStretchControlGraphic only operates on line segments and other subjects that present themselves as a line with two end points.  Some other control graphics, such as MoveControlGraphic, can operate on any subject since all it does is move the entire graphic around.

 

Here is a table of the available control graphics, the type(s) of graphic they operate on, and a description of their purpose.

Control Graphic

Operates on...

Description

AnchorPointControlGraphic

IPointGraphic

Adds a single control point to any graphic defined by a specific anchor point (differs from MoveControlGraphic, which allows a graphic to be moved just by dragging any visible portion of the graphic).

BoundableResizeControlGraphic

IBoundableGraphic

Adds diagonal resize control points to any graphic defined by a bounding box.  Can be constrained to a specific aspect ratio.

BoundableStretchControlGraphic

IBoundableGraphic

Adds orthogonal stretch control points to any graphic defined by a bounding box.

ContextMenuControlGraphic

Any graphic

Adds a context menu to any graphic.  The items of the context menu come from those specified on this graphic and any actions provided by other control graphics in the control chain.

LineSegmentStretchControlGraphic

ILineSegmentGraphic

Adds control points to the end points of any graphic defined as a line segment.

MoveControlGraphic

Any graphic

Adds the ability to move a graphic by dragging any visible portion of the graphic (differs from AnchorPointControlGraphic, which allows a graphic to be moved by dragging the displayed control point).

PolygonControlGraphic

IPointsGraphic

Adds control points to the vertices of any closed graphic defined on an ordered list of points (i.e. the last point in the list will always be the same as the first).  Actions are provided to allow points to be added to and removed from the list dynamically.

TextEditControlGraphic

ITextGraphic

Adds a text edit box to a text graphic that can be invoked by double clicking the text or from a context menu.

TextPlaceholderControlGraphic

ITextGraphic

Adds a single control point to the centre of a text graphic if the text value is empty, allowing the graphic to be moved even if it has no visible portions.  The control point disappears whenever the text value becomes non-empty.

VerticesControlGraphic

IPointsGraphic

Adds control points to the vertices of any open graphic defined on an ordered list of points.  Actions are provided to allow points to be added to and removed from the list dynamically.