Doodle - Part 4: More Power to the User [con't]
In order to offer a range of shape types, the Doodle application must provide some way to select the type of shape that will be inserted next. This information will be used by Doodle whenever the user clicks on the canvas. There's an important distinction between this kind of information (application state) and the information stored in the document; application state has no effect on the structure of the document and only affects how the user interracts with the document or application. We need a mechanism that will monitor the user's choice of shape and modify the application state appropriately when the user changes the selection. In other words, we need a control.
Doodle.Control class provides the base class for all controls in the Doodle application.
While the class itself doesn't do much, it specifies a callback interface (the onUpdate() function) that the application will use to transmit state changes to its controls. Concrete control classes will inherit from this and provide the binding between onscreen user-interraction and the bit of application state they control.
drop-listis a simple user input device that allows the user to select a single item from a from a set of predefined options. This control will be managed by
DropList is constructed with the select object which it will use to interact with the user along with get and set functions which it will use to interract with the application. The initial state of the select object is assigned and the onchange event is handled by a member function.
When the selection object changes, the
DropList transmits the change to the application by calling the
setValue() function. If the application state changes, the
onUpdate() function gives the
DropList the opportunity to modify the onscreen value. In either direction, the new value is compared with the old to avoid problems with infinite loops.
To keep things simple, the set of options is defined in HTML.
The HTML code provides a simple translation from human readable values such as "Point" and "Line" to Application oriented values like 0..3.
Now everything is ready to configure the Doodle application with the new control.
bindControl() function binds an application value type (identified by its enumeration) with a control object, in this case the
Doodle.Control.DropList instance. The
DropList is constructed with the
select object and the get and set functions for the ShapeType property. Note the use of the
Function.prototype.bind() function to provide
Function instances for the
DropList that will act on the Doodle instance.
bindControl() method binds a control to an enumerated value type. This enables the Doodle application to keep track of what controls are connected to what values.
Controls may be updated for each value type by iterating through the list and calling
ShapeType property is handled by two functions.
ShapeType value is modified, the
updateControls() function is called to alert any controls bound to that value that the value may have changed. Note that the value is not passed to the control, only the value type enumeration. The control will retrieve the value from the application in its
The Canvas Reacts
All that's required now is to wait for the user to click somewhere on the canvas to begin inserting a new shape. When called for the first time, the
onMouseDown() function uses the application's shape-type value to create the appropriate widget.
Since each widget expects different amounts and kinds of user interaction to create the completed shape, the canvas will do little more than create the widget and let it decide what to do. If a widget is already being edited (indicated by
this.primaryWidget), the canvas calls into the Widget's
onMouseDown to handle the mouse event. Similarly
onMouseUp call directly into the current