Articles Archive
Articles Search
Director Wiki
 

Drag 'n Drop into a List

May 9, 1999
by Pat McClellan

Dear Multimedia Handyman,

I am new to director, and I am using Dir 6.5. I would like the user to drag the image about on the stage and put the image in the "basket" to represent the chosen prefrence and yet the computer can remember which one is in the "basket".

Ben Wong

Dear Ben

Dragging a sprite around is easy. To do that, you just select the sprite in the score and click on "Moveable" in the score window controls. To keep track of which sprites are "in the basket", we'll need to use some Lingo. Here's a demo movie that you can play with and download. (Download Mac or PC)

First, let's discuss what is really happening when a sprite goes "in the basket". In order to make the basket look like it has a back and front, I've used two different sprites. The first sprite I call "basketTop" includes the black area and the back rim of the basket. All objects going into the basket need to cross in front of this sprite, so I'll put basketTop in sprite channel 1. The other part of the basket is called "basketFront". All of the sprite going into the basket will appear to be behind this part of the basket. So, I need to put basketFront in a higher numbered sprite channel than all of my other sprites.

So, when you drag a sprite (colored ball) into the basket, all you're really doing is dragging it to a point on the stage that is inside of the area that basketFront occupies. Since basketFront is in a higher sprite channel, it appears that the other sprites are going inside. Now let's figure out the lingo part.

What we need to do is have the sprite "know" when it has been dropped inside the target area. To do that, we'll write a mouseUp handler in the behavior so when you release the sprite, it checks to see if its own location is inside the rect of the target sprite. Make sense so far? Next, if it is inside the target, it needs to add its "name" to a list. But, if it is not inside the target, it needs to make sure that its name is not on the list (in case it was there before.)

So our behavior needs to have properties for the target sprite, the target sprite's rect, and a "name" so that we'll be able to identify the sprites we put into the list. We'll also need to have a global variable to hold the list. Here's the behavior.

-- basketDrop Behavior
-- copyright © 1999, ZZP Online, LLC
-- Free use for readers of Director Online
property pMySprite
property pTargetSprite, pTargetRect
property pMyName
global gBasketList
on getPropertyDescriptionList me
  set pdlist to [:]
  addprop pdlist, #pTargetSprite, [#comment:"Target ¬
    sprite number", #format:#integer, #default:1]
  addprop pdlist, #pMyName, [#comment:"Name of this ¬
    object:", #format:#symbol, #default:#item1]
  return pdlist
  
end getPropertyDescriptionList
on beginSprite me
  set pMySprite = the spriteNum of me
  set pTargetRect = the rect of sprite pTargetSprite
  
  if voidP(gBasketList) then
    set gBasketList = []
  end if
  
end
on mouseUp me
  set myLoc = the loc of sprite pMySprite
  
  if inside(myLoc, pTargetRect) then
  
    if getOne (gBasketList, pMyName) then
      nothing
    else
      add gBasketList, pMyName
    end if
    
  else
  
    if getOne (gBasketList, pMyName) then
      deleteOne gBasketList, pMyName
    end if
    
  end if
  
end

When you drop this behavior on a sprite, it will ask you for the sprite number of the target (basketFront), and it wants to know the name of the object. For example, I when I dropped it on the blue ball sprite, I named it "blue".

When the movie plays, the beginSprite handler sets pTargetRect equal to the rect of the target sprite number. This rect is simply a list of points corresponding to the top-left and bottom right corners of the basketFront sprite. The if statement in the beginSprite handler is there just to double check that the gBasketList -- my list of sprite in the basket -- is initialized. (I have a startMovie script which sets gBasketList = []. )

When the sprite is moved and released, the mouseUp handler uses the "inside" Lingo term to see if the loc of the dragged sprite is inside the boundary of the target rect. If so, it checks to see if that sprite is already on the list. If so, then nothing happens, else it adds the name of that sprite to the list. Finally, if the sprite is not inside the target rect, then it checks the list and if its name is on the list, it removes the name.

That's all there is to it. Good luck with your project.

Patrick McClellan is Director Online's co-founder. Pat is Vice President, Managing Director for Jack Morton Worldwide, a global experiential marketing company. He is responsible for the San Francisco office, which helps major technology clients to develop marketing communications programs to reach enterprise and consumer audiences.

Copyright 1997-2017, Director Online. Article content copyright by respective authors.