The Tool
class is an abstract class. There are
abstract subclasses for CAVE tools (CaveTool
) and desktop tools (DesktopTool
).
Each of these abstract classes has concrete subclasses for specific widgets.
A CaveTool
object represents a virtual widget. For convenience, rather then
developing my own virtual widgets, I made use of Jim Costigan's CaveTooLs
widgets [2]. Jim Costigan works for EVL
at UIC, where the CAVE was developed.
In order to use these widgets, they had to be wrapped to conform to the
Tool
interface. Originally, the widgets were not polymorphic. They were
independent classes. Since the widgets were wrapped to the same interface (CaveTool
),
they are now polymorphic. The process of wrapping these widgets is described
in more detail in the Adapter section.
Figure 6.2: Graphical widgets example: Four Motif sliders. Four Costigan virtual sliders
The concrete desktop tools were adapted from X/Motif widgets. In Motif
applications, user defined callbacks define the behavior of the widgets. In
order to preserve the object-oriented design of the model, each instance of a
DesktopTool
instantiates a Motif widget and registers a generic callback. The
generic callback simply calls the update()
method on the desktop tool.
The generic callback:
void genericCB(Widget w, XtPointer client_data, XtPointer call_data) { Tool *tool = (Tool *) client_data; tool->update(); }
Adding the generic callback from within a class method:
XtAddCallback(w, XmNactivateCallback, genericCB, (XtPointer) this);
Using this generic callback mechanism preserves encapsulation. The widget specific code in response to a user event is kept within the class.