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