Chapter 4 Using Activities in ADL

4.3 Using Other Types of System-defined NRO Classes

4.3.1 Mouse NROs

Objects can subscribe to any activity using the standard NRO class. There are some cases, however, where use of special classes makes programming simpler. These special NRO classes are tailored to a particular activity and usually provide simpler argument lists than the general NRO class, making it easier to write the target method.

For example, the use of NROs for mouse events is so common that AM2 provides a special NRO for these events. This NRO returns the client data and the six relevant items about the event in separate variables. Thus, the MouseNro wrapped class sends a message that has seven arguments to the target method:

1. A value of type any containing the NRO's client data

2. An integer with the x coordinate where the mouse-related activity occurred

3. An integer with the y coordinate where the mouse-related activity occurred

4. An integer with the number of the button that was pressed

5. A boolean that is TRUE if the shift key was pressed when the event activity occurred

6. A boolean that is TRUE if the command key was pressed when the event activity occurred

7. A boolean that is TRUE if the modifier key was pressed when the event activity occurred

It is important to emphasize that the use of any of the special NRO forms is entirely optional. It is always possible to use the general NRO object described in Section 4.2, "Using Notification Request Objects" page 62.

The ADL program in Figure 4.4 illustrates the use of special NROs that track the press and release, and the movement of the mouse on a simple shell widget. To do this, we use three different activities: MouseDown, MouseUp and MouseMove. The example uses one instance of the MouseNro class for each activity. The code below shows the complete application.
Using MouseNro Objects
anonymous:XFtop

{

XFlabel reportLabel {x=10; y=10; height=50; width=250;

recomputeSize=FALSE; label="";};

XFbutton exitButton {x=250; y=50; height=50; width=100;

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

MouseNro {'Create, 'MouseDown, self, 'MouseTrack,

"Down"} => downNro;

MouseNro {'Create, 'MouseUp, self, 'MouseTrack,

"Up"} => upNro;

MouseNro {'Create, 'MouseMove, self, 'MouseTrack,

"Move"} => moveNro;

upon Construct

{

exitButton.Pressed = {'Exit, theApp};

{'Subscribe, &downNro} => self;

{'Subscribe, &upNro} => self;

{'Subscribe, &moveNro} => self;

}

on MouseTrack:any clientData, integer xval, integer yval,

integer button, boolean shift, boolean command,

boolean modifier

{

reportLabel.label = "Mouse" & clientData + ":x=" +

toString(xval) & "y="+toString(yval);

}

} myApplication {height=300; width=400;};

4.3.2 Timer NROs

ADL provides a general purpose timer that you can use to trigger actions at pre-specified intervals. To use this timer, subscribe an instance of a class called TimerNro to the application using the special handle named theApp. In a perfect computational environment, the timer activity would always occur when scheduled. However the main event loop of AM2 must handle many events, the duration of which may not be known beforehand. For this reason an actual timer event may be delayed or even missed. In order to help application developers cope with this possibility, TimerNro sends a message with two integer arguments to its clients:

1. A value called late that is the number of milliseconds between the exact time the activity is scheduled and the time it is actually triggered

2. A value called missed that is the number of successive triggering of timer events missed due to delays

For example, consider a simple stopwatch that counts seconds from the time you first press the button until you press it a second time. This clock needs to count intervals of 1000 milliseconds and trigger an activity after each interval. You can do it in the ADL by subscribing the NRO created by the following definition:

TimerNro {'Create, 1000, self,'ClockTick, NULL} => clockNro

The first argument of the Create message is the requested interval (in milliseconds) between triggering of the clock activity. The next three arguments are: the target of the activity's message, the name of the method to receive the message, and a value that can be any ADL type used for conveying client information.

Figure 4.5 shows an ADL program that implements a stopwatch. The example creates three buttons: one for starting the watch, one for stopping the watch, and one for exiting the application. The variable named clock counts the number of seconds once the start button is pressed, and a label displays the elapsed seconds.

The method ClockTick handles the timer activity.
Example Using A Timer
anonymous:XFtop

{

XFbutton start {x=5; y=5; height=30; width=60;

label='Start;};

XFbutton stop {x=70; y=5; height=30; width=60;

label='Stop;};

XFbutton clear {x=135; y=5; height=30; width=60;

label='Clear;};

XFbutton exit {x=135; y=45; height=30; width=60;

label='Exit;};

XFlabel timeValue {x=5; y=45; height=30; width=125;

borderColor='red;borderWidth=1;

recomputeSize=FALSE;};

TimerNro {'Create, 1000, self, 'ClockTick,

NULL}=>clockNro; integer clock;

upon Construct

{

start.Pressed = {'Start, self};

stop.Pressed = {'Stop, self};

clear.Pressed = {'Clear, self};

exit.Pressed = {'Exit, theApp};

'Clear => self;

}

on ClockTick: any cd, integer late, integer missed

{

clock = clock + 1 + missed;

timeValue.label = toString(clock);

}

on Start

{

{'Subscribe, &clockNro} => theApp;

}

on Stop

{

{'Unsubscribe, &clockNro} => theApp;

}

on Clear

{

clock = 0;

timeValue.label = '0;

}

} top { height = 80; width = 200; title="Timer Demo";};

The values provided as arguments by the activity manager give information about the time at which the activity is actually triggered. Line 28 in Figure 4.5 uses the value of the missed argument to correct the counter of seconds.

4.3.1 - Mouse NROs
4.3.2 - Timer NROs

AM2 Documentation - 19 NOV 1996

Generated with Harlequin WebMaker