Chapter 4 Using Activities in ADL
Consider creating a subclass of the XFtop shell widget, which has the property that it always displays the (x,y) coordinates of the mouse in its upper left corner. This type of widget might be useful as a building block in a still image editor that allows the user to crop and scale photographs. The ADL class named LocationTop shown in Figure 4.8 accomplishes this.
The NROs in this class subscribe to both self (the handle to the object itself) and the instance of XFlabel. This is necessary because the XFlabel object can be thought of as though it were "on top" of the instance of LocationTop, to which it belongs. Any mouse-related events on the label trigger the activities of the label. They are not passed through to the underlying XFtop. If lines 17 through 19 were removed from the class declaration, the label would act as a "hole" in the widget; events may trigger the activities of the label, but there are no registered NROs and the activities of the label would therefore have no effect.
In some situations, an application developer using ADL needs to add a new activity to a class that inherits activity management from a base class. Consider a class that displays a color palette. We would like such a class to have an activity called ColorSelected that provides the name of the chosen color in the message sent when an event triggers the activity. Since our color palette class inherits from the AM2 wrapped class XFlayout, which already manages activities, our new class automatically has the capability to manage any activity. We need only add the new activity and define what should be done when an event triggers the activity.
Figure 4.9 shows an implementation of the ColorPalette class. This ADL code is a simplified version of a more general color palette provided in the ADL standard library. In the simplified version the color palette has exactly eight colors, the buttons for these colors are fixed in size, and the layout of the eight colored buttons in the palette is horizontal. All of these restrictions are relaxed in the more complete version.
The ColorPalette class inherits from the XFlayout class, thereby inheriting its members, methods and activity management capabilities of that class. The member colorList in the ColorPalette class (defined on lines 5 and 6) provides the names of the colors in the palette. The other class member, buttonArray, is an array of lists. After an instance of a ColorPalette is constructed, each element of this array is a list of two handles: a handle to a button and a handle to an NRO for that button. The index for this array is an integer between one and eight, and corresponds to the positions of the elements in the colorList.
The most significant component of this example is line 9, which causes the initialization of the member ActivityInfo. This list is inherited from the base class XFlayout. The sublist in ActivityInfo provides the information about managing additional activities; each entry in the list corresponds to a different new activity. The general form for the sublists is:
{<name of activity>, {<keyname1>,<keyname2>, ...}}
Thus, in Figure 4.9 the name of the new activity is ColorSelected, and the single key provided to any target of this activity has a single entry called Color.
The Construct method for the ColorPalette class simply sets the default height and width of the palette. The Init method for the ColorPalette class starting at line 19 does most of the work of setting up the buttons and handles in the class. It uses the new operator to create instances of buttons and NROs from the heap, and then stores the handles to these buttons and NROs as elements of the buttonArray. It also subscribes an NRO to each button, using the background color in each of the buttons as the client data in the vanillaNro instance. Thus, when a user presses any of the eight buttons, the ColorChosen method of the ColorPalette receives a message with the color of the button as the client data.
The Destroy method starting on line 36 recovers the memory allocated for buttons and NROs when an instance of a ColorPalette is created. This method automatically receives a message whenever a ColorPalette is no longer valid or when the delete operator is applied to a handle to a ColorPalette object. The implementation of this method loops through the array of buttons and deletes the buttons and their corresponding NROs.
The method named ColorChosen is the target for the message sent when a user presses any of the eight buttons. This method simply calls the method TriggerNotification, which is inherited in any class derived from a class that manages activities. It is this method that then sends messages to every NRO subscribed to the activity. For example in line 49, the message takes the form:
{'TriggerNotification, 'ColorSelected, {cdata} } => self;Note that the TriggerNotification method always takes two arguments: a string giving the name of the activity that was triggered and a list of values transmitted to the target. In this case, the activity name is ColorSelected, and the list of values has the name of the selected color.
Figure 4.10 illustrates how the ColorPalette class might be used. The most notable aspect of this program is that once implemented, the activitymanagement capabilities of the ColorPalette class are treated exactly the same as the corresponding capabilities of standard wrapped classes such as XFbutton and XFtext.
Another situation of interest to the ADL programmer is the need to create a class that manages activities but does not inherit from a standard wrapped class that manages activities. In this situation, the programmer inherits from an ADL class called ActivityManager which supplies the needed functionality.
The ActivityManager class is an example of a class designed specifically for inheritance purposes. It has the following functionality:
Classes such as Movable are intended for use as a base class in combination with other classes. For example, a class might inherit from both the XFlabel wrapped class and the Movable class, thereby inheriting the activities, members and methods of both base classes. This type of class is often referred to as a mix-in class.
Figure 4.11 displays the ADL code that implements the Movable class. The member ActivityInfo declares the name of the new activity (Update) and the list of keys for that activity. The example uses three instances of the MouseNro class to subscribe to the MouseUp, MouseDown and MouseMove activities.
The Construct method subscribes the three NROs to the object itself. Note that the Subscribe messages in this method on lines 12 through 14 are sent to the handle derived::self. The derived keyword in ADL indicates that the message goes to the object that is at the end of the chain of inheritance (i.e. the member of the "most derived" class).
This is necessary because the MouseDown, MouseUp and MouseMove activities are not activities managed by the Movable class. Rather, they are managed by whatever class we mix-in with the Movable class. Sending the Subscribe message to derived::self ensures that the NROs are subscribed to the correct activity manager.
Lines 17 through 22 implement the method named Down that receives a message when the MouseDown activity is triggered. This method stores the location of the mouse when the button pressed.
The method Move shown in lines 24 through 29 change the (x,y) coordinates of the object when the mouse has been moved. Note again that we must use the derived keyword before the attributes x and y because they do not belong to the Movable class; they must exist in the class derived from the Movable class.
The last method, Up, triggers the Update activity notification by sending the TriggerNotification message. It provides the new (x, y) coordinates of the object as part of them message, and then disarms the object. Figure 4.12 shows a simple case using the class.
Lines 7 through 26 declare an anonymous class derived from the XFtop wrapped class. This class has an instance of a MovableLabel and an instance of an XFlabel. The latter of these two is used to display the (x,y) coordinates of the former. The NRO named updateNro subscribes to the Update activity. This NRO causes the method ChangeLocation to receive a message when the Update activity is triggered. This method, defined in lines 21 through 25, changes the value of the label named location to indicate the new coordinates of MovableLabel.
Generated with Harlequin WebMaker