class drawmode { 
\fbox{drawmode}
public: enum { move, box, circle, arrow, lastmode }; }; class tablet : public canvas {
\fbox{tablet}
public: tablet(widget* w, char* options=""); int operator()() {
\fbox{operator()}
return handlers [mode]->dispatch(tk,argc,argv); } void mode(char* m); protected: void init(char* options); int _mode; class handler* handlers[drawmode::lastmode]; canvas* c; };

slide: The {\em tablet}

Defining actions

The most important component of our drawtool application is defined by the tablet widget class depicted in slide draw-tablet. The various modes supported by the drawing tool are enumerated in a separate class drawmode. The tablet class itself inherits from the canvas widget class. This has the advantage that it offers the full functionality of a canvas. In addition to the constructor and operator() function, which delegates the incoming event to the appropriate handler according to the {\em _mode} variable, it offers a function mode, which sets the mode of the canvas as indicated by its string argument, and a function init that determines the creation and geometrical layout of the component widgets. As instance variables, it contains an integer {\em _mode} variable and an array of handlers that contains the handlers corresponding to the modes supported. See section canvas for an example of a typical canvas handler.

Dispatching

Although the tablet must act as a canvas, the actual tablet widget is nothing but a frame that contains a canvas widget as one of its components. See slide tablet-op.
  tablet::tablet(widget* w, char* options)  
\fbox{tablet}
: canvas(w,"tablet",0) {
(a)

widget* top = new frame(path()); init(options); redirect(c);
(b)

handler(this);
(c)

handlers[drawmode::move] = new move_handler(this); handlers[drawmode::box] = new box_handler(this); handlers[drawmode::circle] = new circle_handler(this); handlers[drawmode::arrow]=new arrow_handler(this); _mode = drawmode::move; }

slide: Installing the handlers

This is reflected in the invocation of the canvas constructor (a). By convention, when the options parameter is 0 instead of the empty string, no actual widget is created but only an abstract widget, as happens when calling the widget class constructor. Instead of creating a canvas right away, the tablet constructor creates a top frame, initializes the actual component widgets, and redirects the eval, configure, bind and handler invocations to the subordinate canvas widget (b). It then declares itself to be its own handler, which results in declaring itself to be the handler for the canvas component (c). Note that reversing the order of calling redirect and handler would be disastrous. After that it creates the handlers for the various modes and sets the initial mode to move. The operator() function takes care of dispatching calls to the appropriate handler. The dispatch function must be called to pass the tk, argc and argv parameters.