Chapter 5 Example ADL Programs

5.3 A Picture Button Class

In this example we create a class, called PictureButton, that behaves like a standard AM2 button but has an image displayed within its borders rather than a text label. This class manages an activity called Pressed that accepts subscriptions from standard ADL Notification Request Objects (NROs).

As with a standard ADL button, the PictureButton class shows a highlighted border when the mouse is pressed down on it. The button triggers the activity when the mouse is released, but only if the release occurs while the mouse is still positioned on top of the image. This allows the user of the PictureButton to change his or her mind after the mouse is depressed by rolling the mouse cursor outside of the image.

By default, a PictureButton object is sized automatically to the match the size of the image inside of it. The programmer using the PictureButton class can change the position in the button where the image is displayed and can override the default size or the image by cropping or zooming. This is done by resetting any of the following six members of the class:

1. xloc - An integer indicating the starting x position where the upper left corner of the image is displayed. This defaults to 0.

2. yloc - An integer indicating the starting y position where the upper left corner of the image is displayed. This defaults to 0.

3. clipW - An integer indicating the clipped width of the image that is displayed. The default value of -1 is used to indicate that the width of the image is not to be clipped.

4. clipH - An integer indicating the clipped height of the image that is displayed. The default value of -1 is used to indicate that the height of the image is not to be clipped.

5. offsetX - An integer indicating where along the x dimension in the source image the displayed image is to start. This value is used to clip the left side of the image. The default value is 0, indicating no clipping.

6. offsetY - An integer indicating where along the y dimension in the source image the displayed image is to start. This value is used to clip the top of the image. The default value is 0, indicating no clipping.

5.3.1 ADL Implementation of the PictureButton Class

Here is the ADL code for the PictureButton class, with detailed comments on specific lines.
PictureButton Class
class PictureButton: XFvisual

{

string fname; /* name of file where image is stored */

handle pimage; /* handle to image object */

boolean armed = FALSE; /* flag for whether button is armed */

boolean hilighted = FALSE; /* flag for whether button is hilighted */

string hilightColor = "LightYellow"; /* highlight color for border */

string nohilightColor = "Black"; /* regular color for border */

Nro {'Create, 'MouseDown, self, 'ShowDown, {}} => nroDown;

Nro {'Create, 'MouseUp, self, 'ShowUp, {}} => nroUp;

MouseNro {'Create, 'MouseMove, self, 'ShowMove, {} } => nroMove;

/* parameters for image presentation */

boolean defaultSize=TRUE; /* use width and height of image */

integer xloc=0; /* location where image is presented */

integer yloc = 0; /* "" */

integer clipW= -1; /* the clipping width--default no clip */

integer clipH = -1; /* the clipping height--default no clip */

integer offsetX = 0; /* the x offset of source image */

integer offsetY = 0; /* the y offset of source image */

list ActivityInfo = {{'Pressed, {}}};

list Pressed={};

Nro {'Create, 'Pressed, NULL, "",TRUE} => nroPress;

/* Construct method for class */

upon Construct: string f

{

{'Startup,f} => self;

}

/* Create method for class */

upon Create: string f, handle hparent

init {{'Create, hparent} => XFvisual}

{

{'Startup,f} => self;

}

on Startup: string f

{

fname = f;

borderColor = nohilightColor;

borderWidth = 1;

}

/* Init method to load image,present, scale image and register NROs*/

on Init

{

pimage = new {'Construct, {'MEimage, {'MAfile, fname}}} =>MMimage;

if(defaultSize) {

height = pimage->height - offsetY;

width = pimage->width - offsetX;

if(clipW > 0) {

width = clipW-offsetX;

}

if(clipH > 0) {

height = clipH-offsetY;

}

}

else {

{'Zoom, toReal(width)/toReal(pimage->width),

toReal(height)/toReal(pimage->height)} => pimage;

}

{'PresentClipped, self, xloc, yloc,clipW, clipH,

offsetX, offsetY} => pimage;

{'Subscribe, &nroDown} => self;

{'Subscribe, &nroUp} => self;

{'Subscribe, &nroMove} => self;

}

/* Method called when mouse is moved */

on ShowMove: any whatever, integer xval, integer yval, integer nbut,

boolean shift, boolean command, boolean modifier

{

if (armed && xval>=0 && xval < width && yval>=0 && yval<height) {

borderColor = hilightColor;

hilighted = TRUE;

}

else if(armed &&(xval<0 || xval>=width || yval<0 || yval>=height)) {

borderColor = nohilightColor;

hilighted=FALSE;

}

}

/* Method called when mouse is pressed */

on ShowDown: any whatever, list keys, list values

{

armed = TRUE;

hilighted = TRUE;

borderColor = hilightColor;

}

/* Method called when mouse is released */

on ShowUp: any whatever, list keys, list values

{

if (armed) {

armed = FALSE;

borderColor = nohilightColor;

if (hilighted){

{'TriggerNotification, 'Pressed, {}} => self;

if (Pressed != {}) {

at(1, Pressed) => at(2, Pressed);

hilighted = FALSE;

}

}

}

/* destructor method for the class */

on Destroy

{

delete pimage;

}

}; /* end of class PictureButton */

Line 1 declares the beginning of the definition of the PictureButton class. This class inherits from the XFvisual class. The inheritance from the XFvisual class provides the ability to display an image and manage standard mouse activities such as MouseDown, MouseUp and MouseMove.

Line 3 declares the member fname. This is a string that is used to hold the name of the file that stores the image for the button.

Line 4 declares a handle member named pimage. This stores the handle to the MMimage object that holds the actual image that appears on the PictureButton object.

Lines 5-6 declare two boolean members. The first of these, called hilighted, is a flag that indicates whether the border around the button is highlighted. This value is set to TRUE when the mouse is depressed on the PictureButton. The second boolean, armed, is set to true when the button is armed (i.e. when a release of the mouse on the image results in the Pressed activity being triggered.)

Lines 7- 8 declare the members hilightColor and nohilightColor. These strings contain the names of the colors used for the border of the PictureButton. They are initialized to their default values of LightYellow and Black respectively. The programmer using the class can override these defaults.

Lines 9-11 declare three NRO members of the class. These three NROs are used to deal with MouseDown, MouseUp and MouseMove activity. The first two are instances of the Nro class. The NRO for the MouseMove activity is an object of the MouseNro class because we will use the (x,y) coordinates of MouseMove events in the activity handler method, ShowMove.

Line 13 declares the boolean member defaultSize. This is set TRUE when if the button is to be sized to match the image displayed within it.

Lines 14-19 declare the six integer values that describe the clipping and scaling of the image to be displayed. They are all initialized to their default values.

Line 20 declares a list named ActivityInfo. This list is used by the ADL activity manager to determine what additional activities (beyond those in the base classes) are to be managed. In this case, the Pressed activity is added.

Line 21 declares the member Pressed. This value is set by the user of the PictureButton class to set the target and message to be sent when the button is pressed.

Line 22 creates an NRO that will be used by the Pressed activity. It is initialized with its target set to NULL.

Lines 24-27 define the special constructor Construct. This method just invokes the method named Startup.

Lines 29-33 define the special constructor Create. This method is used when an instance of the PictureButton class is created from the heap. It send the base class initialization message to the XFvisual base class, informing that class about the handle to the parent of the widget. It then invokes the method named Startup.

Line 34 defines the method called Startup. This method is invoked by both the Create and Construct methods. Its sole argument is the name of the file containing the image to display.

Line 36 assigns the argument f to the member fname. This member contains the name of the file that stores the image.

Line 37 assigns the default color nohighlightColor to the widget's borderColor.

Line 38 sets the value of the widget's borderWidth to 1.

Line 40 begin the Init method for the class. This method is automatically invoked as the last step in the creation of any object in AM2.

Line 43 uses the new operator to create an instance of the MMimage object. Construct, the special constructor for this object, is messaged with a list argument that has a string with the type of the element (MEimage), and a list containing a pair of values, specifically the type of image storage (MAfile), and the name of the file that stores the image (fname). The handle pimage is assigned the handle returned by the special constructor.

Lines 45-46 set the height and width of the PictureButton to the height and width of the image if the button is supposed to be sized automatically.

Lines 47-51 determine the clipped width and height of the button.

Lines 55 -56 are executed if the image is to be zoomed to a preset size. They invoke the Zoom method on the image.

Lines 58-59 causes the image to be presented in the button.

Lines 60 -62 subscribe the NROs to the object.

Lines 65 -76 implement the ShowMove method that is messaged whenever a MouseMove activity is triggered. This method checks if the button is armed from an earlier MouseDown event. If it is, the method turns the highlighting of the image on and off depending on whether the mouse is located inside or outside the button. This gives the user visual feedback as to whether releasing the mouse will cause the button to be pressed.

Lines 78-83 implement the ShowDown method. This method is messaged when the NRO downNro is triggered. The method arms and highlights the button.

Lines 85- 98 implement the ShowUp method. This method is messaged when the NRO upNro is triggered. The method checks if the button is armed. If it is, the value of armed and borderColor are reset, and the method checks whether the button is highlighted. If it is highlighted, then it calls the TriggerNotification method. This method is part of the activity management mechanism. In this case, the implementation of TriggerNotification is inherited from the XFvisual base class. The TriggerNotification method takes two arguments: the name of the activity and the list of values to be sent to the target of the activity. In this case, the Pressed activity is triggered and the argument list is empty.

The ShowUp method also checks to see if the Pressed member of the PictureButton class has been set. This member is a list that can be set by the user of the class as a shortcut for setting a single action to be taken when the button is pressed. This mechanism exactly parallels the use of the Pressed member in standard ADL button widgets.

Lines 100-103 define the Destroy method for the class. This method is automatically messaged whenever an instance of the class is deleted. This occurs when an automatic instance of that type goes out of scope or when the delete operator is called on an instance created using the new operator. The Destroy method deletes the memory allocated for the MMimage instance where the image was stored.

Line 104 is the end of the definition of the class PictureButton.

5.3.2 An Example Using the PictureButton Class

Given the code shown above, we now turn to a simple ADL program that uses the PictureButton class. The example puts an instance of a PictureButton on the screen along with a text label for that button. Pressing the PictureButton reverses the visibility of the label. Here is the ADL code.
PictureButton Class Example
anonymous: XFtop

{

PictureButton {'Construct, "dragon.gif"} => button1

{borderWidth = 2; x = 50; y = 75;};

XFlabel mylabel {x=120;y=300;label="Picture of Dragon";};

XFbutton exitButton {x=50; y=350; height=45; width=100;

borderWidth=0; recomputeSize=FALSE; label="Exit";};

Nro {'Create, 'Pressed, self, 'BPress, {}} => nroPress;

upon Construct

{

{'Subscribe, &nroPress} => button1;

exitButton.Pressed = {'Exit, theApp};

}

on BPress: any cdata, list keys, list values

{

mylabel.visible = !mylabel.visible;

}

} myTop {height=400; width=500; title="Picture Button Demo"};

Line 1 starts the definition of an anonymous instance of an object that inherits from the ADL top level shell class, XFtop. (We use anonymous to create a single instance or very few instances of a class.)

Lines 3-4 declare a member of this anonymous class that is an instance of a PictureButton named button1. The image that is displayed on the button is in the file dragon.gif. The button has a border that is two pixels wide and is at (x,y) coordinates (50,75).

Line 5 declares an XFlabel at coordinates (120,300) that has the text label Picture of Dragon.

Lines 6-7 declare an XFbutton at coordinates (50,350) that is 45 pixels high and 100 pixels wide. This button has no border and its size is not adjusted depending on the space needed for the button's label. The button contains the text Exit.

Line 9 declares an instance of an Nro. This NRO's activity is Pressed and it sends a message to the BPress method of self when triggered.

Lines 10-14 define the Construct method for the shell object. The body of this method subscribes nroPressed to the PictureButton and sets the Pressed attribute of the XFbutton named exitButton so that the Exit message is sent to the application when that button is pressed.

Lines 16-20 define the method BPress. This is the method invoked when the Pressed activity of PictureButton is triggered. The body of this method reverses the visible attribute of the label.

Line 21 closes the declaration of the shell widget. The height and width of the shell widget are set in an izor block.

5.3.1 - ADL Implementation of the PictureButton Class
5.3.2 - An Example Using the PictureButton Class

AM2 Documentation - 19 NOV 1996

Generated with Harlequin WebMaker