6 Moving Stations

Having created the Stations, the next task is to make it possible to move them around. The moving of a Station is simple to do, since a Station is a Picture which in turn is a specialization of AbstractGraphicalObject. A reference to an AbstractGraphicalObject can be entered to the InteractiveMove attribute of myCanvas, that does exactly what is needed in this case. Thus the only thing to do is to change onMouseDown of myCanvas to handle the situation right. If the mouse is pressed outside any existing Stations, a new one must be created as above. If the mouse is pressed inside an existing Station, then an interaction for moving this station should be started. One way to find out if anything was hit is by scanning through all graphical objects in the Picture of myCanvas, and for each graphical object check whether the mouse position is contained within this graphical object. An exception has to be made for the city map, which must never be moved around. In subway4.bet, onMouseDown becomes

onMouseDown:: 
  (# 
  do (* Transform mousepos to BifrostCanvas coordinates *)
     mousepos->devicetocanvas->mousepos;
      
     scan: 
       (# (* Find out what was hit - if any *)
       do thePicture.ScanGOsReverse
          (# 
          do (if (myCanvas[], mousepos)->go.containspoint then
                 (if go[]
                  // map[] then (* ignore *)
                  else
                     (* We hit a Station: Move it *)
                     (go[], mousepos, NoModifier)
                       -> interactivemove;
                     leave scan
                 if);
             if);
          #);
          (* Nothing was hit *)
          mousepos->makeStation;
       #);
  #);

The Picture used to hold the graphical objects of myCanvas is called thePicture. The graphical objects in thePicture are scanned using the control pattern ScanGOsReverse. This control pattern scans through the objects in the Picture downwards from the top (frontmost) graphical object. Using go.containspoint it is checked if the mouse was inside the graphical object, and if so, the scanning is stopped, except if the graphical object was the map. If a Station was 'hit', a reference to it is passed to interactivemove. The Modifier parameter to interactivemove is used to specify what keyboard modifiers should be used to constrain the interaction. In this case NoModifier is specified, meaning that the interaction cannot be constrained. If no Station was hit, makeStation is invoked as before.


The Bifrost Graphics System - Tutorial
© 1991-2004 Mjølner Informatics
[Modified: Sunday October 15th 2000 at 15:36]