Interacting With The Slider Object

In part 1, we created a script for making a 'slider object' that is designed to draw a list of images into another image and 'slide' the list of images along. To create a new instance of this script, we need to do the following three things:

  • Create a new instance using the new command
  • Initialise this instance (specifying the output image, and the rect)
  • Provide a list of images to use

The following lingo (from a behaviour on a sprite that will display the sliding images) illustrates this process:

property mySlider



on beginSprite me

  

  thisSprite = sprite(me.spriteNum)

  thisMember = thisSprite.member

  thisCanvas = thisMember.image

  imageList = GetListOfImages()

  

  -- create the slider object

  mySlider = script("HorizontalImageSlider.Class").new()

  mySlider.Initialise(thisCanvas, thisCanvas.rect)

  mySlider.LoadImages(imageList)



end

Interacting with the Slider Object can be straightforward. For example, the following behaviour will slide the images along 10 pixels each time it is clicked:

property mySlider



on beginSprite me

  

  thisSprite = sprite(me.spriteNum)

  thisMember = thisSprite.member

  thisCanvas = thisMember.image

  imageList = GetListOfImages()

  

  -- create the slider object

  mySlider = script("HorizontalImageSlider.Class").new()

  mySlider.Initialise(thisCanvas, thisCanvas.rect)

  mySlider.LoadImages(imageList)

  

end 



on mouseUp (me)

  mySlider.Slide(10)

end

If you want to show which tile is clicked on, you can use the SelectTile() method, passing the point on the slider that was clicked. For example:

property mySlider, myOffset



on beginSprite me

  

  thisSprite = sprite(me.spriteNum)

  thisMember = thisSprite.member

  thisCanvas = thisMember.image

  imageList = GetListOfImages()

  

  -- create the slider object

  mySlider = script("HorizontalImageSlider.Class").new()

  mySlider.Initialise(thisCanvas, thisCanvas.rect)

  mySlider.LoadImages(imageList)

  

  myOffset = point(thisRect.left, thisRect.top)

  

end 



on mouseDown (me)

  ClickedTile = mySlider.GetTileAtPoint(the mouseLoc - myOffset)

  if voidP(ClickedTile) then return -- no tile clicked

  mySlider.SelectTile(ClickedTile)

end

This behaviour is a little more complicated than the previous because it needs to map the mouse location to a point within the slider. To do this, the behaviour subtracts an 'offset' (the distance from the top-left of the slider to the top-left of the screen) from the mouseLoc.

By separating the generic 'Slide Images' script from the specific behaviour that creates and interacts with the SliderObject, you can focus on fine-tuning the behaviour, adjusting how quickly the images slide, what images to show and so on, without having to worry about the details of how the SliderObject is implemented. This encapsulation of behaviour and data into little 'black boxes' is one of the advantages of adopting an 'object orientated' view when developing with lingo.

More sophisticated ways to interact with the SliderObject.

The following behaviour is an example of a behaviour which allows you to 'click and drag' the images along, or 'auto-scroll' the images depending on where the mouse is relative to the centre of the sliding images.

Note, in this example, the behaviour creates and then sets the SliderObject as its ancestor. This means, for example, you could send a SelectTile message to the sprite, and it would respond using the SelectTile method of the SliderObject (rather than requiring code to manually route the message through to the Slider).

property ancestor

property myMidH, myShift, myAlpha, myOffset

property myTrackingFlag, myStartH

property mySlideLeftRect, mySlideRightRect



on beginSprite me

  

  thisSprite = sprite(me.spriteNum)

  thisRect = thisSprite.rect

  thisMember = thisSprite.member

  thisCanvas = thisMember.image

  thisCanvas.fill(thisCanvas.rect, rgb("#000000"))

  

  --

  myOffset = point(thisRect.left, thisRect.top)

  myMidH = thisSprite.left + (thisSprite.width/2)

  

  -- get a list on images to show

  fndImages = me._GetImages()

  

  -- create the slider object

  ancestor = script("HorizontalImageSlider.Class").new()

  me.Initialise(thisCanvas, thisCanvas.rect)

  me.LoadImages(fndImages)

  

  -- create the 'hot spots' for sliding

  mySlideLeftRect = rect(thisSprite.left, thisSprite.top, thisSprite.left \

 + (thisSprite.width/3), thisSprite.bottom)

  mySlideRightRect = rect(thisSprite.right-(thisSprite.width/3), \

thisSprite.top, thisSprite.right, thisSprite.bottom)

  

end



on endSprite (me)

  -- clean up the canvas 

  thisSprite = sprite(me.spriteNum)

  thisMember = thisSprite.member

  thisCanvas = thisMember.image

  thisCanvas.fill(thisCanvas.rect, rgb("#000000"))

end	



on enterframe (me)

  if myTrackingFlag then

    -- the mouse was clicked on this sprite

    if not (the mouseDown) then 

      -- stop tracking

      myTrackingFlag = 0

    else

      -- 'drag' the slider to the current mouse location

      mH = the mouseH

      amt = myStartH - mH

      myStartH = mH

      me.Slide(amt)

    end if

  else

    p = the mouseLoc

    if inside(p, mySlideLeftRect) then

      proposedAmt =  myShift -1

      myShift = Max(-50, proposedAmt)

      

    else  if inside(p, mySlideRightRect) then

      proposedAmt =  myShift + 1

      myShift = Min(50, proposedAmt)

      

    else

      -- slow down to a stop

      myShift = myShift * 0.75

      if abs(myShift) < 2 then myShift = 0

    end if

    me.Slide(myShift)

  end if

end



on mouseDown (me)

  ClickedTile = me.GetTileAtPoint(the mouseLoc - myOffset)

  if voidP(ClickedTile) then return -- no tile clicked

  myTrackingFlag = 1

  myShift= 0

  myStartH = the mouseH

  -- if the shift key is pressed, allow multiple selections

  me.SelectTile(ClickedTile, (the shiftDown))

end



on _GetImages (me)

  

  fnd = []

  mx = (the number of members of castlib "Images")

  repeat with i = 1 to mx

    m = member(i, "Images")

    fnd.append(m)

    

  end repeat

  return fnd

  

end

Note - this last _GetImages method simply collects references to all the members of a castlib called "images". Techniques for getting a dynamic list of images either locally (for Projectors) or online (for Shockwave) will be discussed in the next section.

Downloads

Source Movie is available here

First published 07/06/2005