Route Scripts

Handling Multiple Items

When the user selects multiple items from the overview, the target should no longer be a single soup entry, but is instead a multiple item target. There are some global routines which manipulate these multiple item targets:

CreateTargetCursor(class, dataArray)

Returns a multiple item target of class class given the array of frames in dataArray.

TargetIsCursor(target)
Returns true if target is a multiple item target, nil otherwise.

GetTargetCursor(target, param2)

Returns a cursor object from target. (The param2 parameter is currently unused--set it to nil.) If target isn't a multiple item target, the return result is a cursor which iterates over a single entry, target.


Note:GetTargetCursor doesn't return an actual soup cursor (as discussed in "Queries/Cursors" on page 239). Instead, it returns a frame which provides Prev, Next, and Entry methods to iterate through multiple items.


NewtOverLayout takes care of calling CreateTargetCursor and setting the target slot. We just have to rewrite our routeScript function to account for multiple items. Here's our first try at the new routeScript:

routeScript: func(target, targetView)
begin
   if not TargetIsCursor(target) then 
      PlaySoundSync(ROM_plinkBeep);
   else begin 
      local c := GetTargetCursor(target, nil);
      local e := c:Entry();
      while e do begin
         // plays a sound
         PlaySoundSync(ROM_plinkBeep);
         e := c:Next();
      end;
   end;
end,
The preceding code will work correctly. We can simplify it, however, by taking advantage of the fact that GetTargetCursor will return a cursor even if its parameter isn't a multiple item target:

routeScript: func(target, targetView)
begin
   local c := GetTargetCursor(target, nil);
   local e := c:Entry();
   while e do begin
      // plays a sound
      PlaySoundSync(ROM_plinkBeep);
      e := c:Next();
   end;
end,
If our routeScript gets called and the target isn't a multiple item target, GetTargetCursor will return an object. This object will return target when sent the Entry message and will return nil when sent the Next message.

The final thing we need to handle is the case where nothing is selected. Duplicate and Delete don't even appear in the Action menu if nothing is selected. It would be nice if Beep worked the same way. We'll have to switch from providing a title slot in our extraRouteScripts array item to providing a GetTitle function.

4. Here is our revised extraRouteScripts array:

[
   {
      title: "Beep",
      GetTitle: func(target)
      begin
         if target then
            "Beep"
         else
            nil   
      end,

         //   too lazy to create our own icon here
      icon: ROM_routeDuplicateIcon,
   routeScript: func(target, targetView)
   begin
      local c := GetTargetCursor(target, nil);
      local e := c:Entry();
      while e do begin
         // plays a sound
         PlaySoundSync(ROM_plinkBeep);
         e := c:Next();
      end;
   end,
   }
]
The code returns the string "Beep" if there is a non-nil target, and returns nil if the target is nil. That way, "Beep" only shows up if there is a target. Now, if no item is selected and the Action button is tapped, the user is shown the alert in FIGURE 12.7.

FIGURE 12.7 : Alert when Action button is tapped when nothing was selected.


An online version of Programming for the Newton using Macintosh, 2nd ed. ©1996, 1994, Julie McKeehan and Neil Rhodes.

Last modified: 1 DEC 1996