-- MOUSE STATES -- -- -- © 31 May 2000, James Newton -- PROPERTIES -- property spriteNum -- author-defined parameters property buttonID -- used to identify this instance during -- sendAllSprite calls property activeFlag -- if FALSE, the button will not react -- property standardImage -- member displayed when mouse is elsewhere property rolloverImage -- member displayed when mouse is over sprite property mouseDownImage -- member displayed when sprite is clicked property inactiveImage -- member displayed when activeFlag is FALSE -- property cursorType -- built-in cursor|cursor member|1 bit bitmap property builtInCursor -- integer cursor number property cursorMember -- cursor member reference property customCursor -- 16x16 pixel 1-bit bitmap member reference property customMask -- 16x16 pixel 1-bit bitmap member reference -- internal properties property mySprite -- sprite(me.spriteNum) property myCursor -- integer cursor number | [member number] property mySavedCursor -- sprite(0).cursor before rollove property myMouseOver -- TRUE if the mouse is over the sprite property myMouseDown -- TRUE if mouse was clicked down on sprite -- PUBLIC METHODS -- on toggleActive(me, newState, IDorList) ------------------------------ -- Sent from another script -- -- * Sets activeFlag to TRUE if newState is a non-zero integer, and -- to FALSE if newState is zero. If newState is then -- activeFlag is toggled to its opposite value. -- -- Syntax: -- can be: -- - , in which case the message will be acted on anyway; -- - a string, in which case the message is acted on if IDorList -- is the same as the current buttonID; -- - a linear list, containing the buttonIDs of those buttons -- which should react to the call; -- - a property list, with data which overrides newState. -- -- Special case: newState may be a property list, in which case -- a buttonID property/integer value pair will be acted on. -- -- Examples: -- -- sendAllSprites(#toggleActive, TRUE) -- -- all buttons are activated -- -- sendAllSprites(#toggleActive) -- -- all buttons are toggled to their opposite state -- -- sendAllSprites(#toggleActive, 1, "Button 1") -- -- only button 1 is activated: other buttons are left as is -- -- sendAllSprites(#toggleActive, 1, ["Button 1", "B2"]) -- -- "Button 1" and "B2" are activated, others are left as is -- -- sendAllSprites(#toggleActive, 0, ["Button 1": 1]) -- -- all buttons are now off, except for button 1 which is now on -- -- sendAllSprites(#toggleActive, void, ["Button 1": 1]) -- -- all buttons are toggled to their opposite state, except for -- button 1 which is turned on -- -- sendAllSprites(#toggleActive, ["B1": 1, "B2": 0]) -- -- "B1" is activated, "B2" is disactivated, others are left as is -- -- To ensure that only "Mouse State" instances are affected by the -- #toggleActive message, you can first create a list of -- "Mouse State" instances, using the getReference() method, then -- call the list: -- -- buttonReferenceList = [] -- sendAllSprites(#getReference, buttonReferenceList, #mouseStates) -- call(#toggleActive, buttonReferenceList, ) -------------------------------------------------------------------- if voidP(mySprite) then -- This message has been received before the beginSprite event mySprite = sprite(me.spriteNum) end if case ilk(IDorList) of #string: if IDorList <> buttonID then exit end if #list: if not IDorList.getPos(buttonID) then exit end if #propList: IDorList = IDorList[buttonID] if integerP(IDorList) then newState = (IDorList <> 0) end if end case case ilk(newState) of #integer: activeFlag = (newState <> 0) #propList: newState = newState[buttonID] if integerP(newState) then activeFlag = (newState <> 0) else exit end if otherwise activeFlag = not activeFlag end case if activeFlag then mySprite.member = standardImage if rollover(spriteNum) then me.showRollover() end if else me.showRolloff() end if end toggleActive on getReference(me, theList, behaviorID) ----------------------------- -- Sent from another script -- -- * Provides a pointer to this instance, either by adding the -- parameter to , or by returning it. If a property list -- is used, the sprite's #buttonID property is provided as the -- property for its value. -- -- If is a symbol, it will be used to filter for this -- behavior: any symbol other than #mouseStates will prevent this -- handler from reacting to the #getReference call. -- -- Examples: -- -- buttonReferenceList = [] -- sendAllSprites(#getReference, buttonReferenceList) -- put buttonReferenceList -- -- [, ] -- -- buttonReferenceList = [:] -- sendAllSprites(#getReference, buttonReferenceList, #mouseStates) -- put buttonReferenceList -- -- ["Button 1": ] -- -- buttonReference = sendSprite(1, #getReference) -- put buttonReference -- -- -- -- Note that a propList will collect the buttonIDs of each instance -- of this behavior. Such a list can be used with the the -- toggleActive() method to treat each button individually. -------------------------------------------------------------------- if symbolP(behaviorID) then if behaviorID <> #mouseStates then exit end if end if case ilk(theList) of #list: theList.append(me) #propList: theList.addProp(buttonID, me) otherwise return me end case end getReference -- SPRITE EVENT -- on beginSprite(me) mySprite = sprite(spriteNum) mySavedCursor = sprite(0).cursor -- Decide which cursor to use during rollovers case cursorType of void, "Built-in cursor": myCursor = builtInCursor "Cursor member": cursorMember = value(cursorMember) myCursor = [cursorMember.number] "1 bit bitmap": customCursor = value(customCursor) myCursor = [customCursor.number] if customMask <> "no mask" then customMask = value(customMask) myCursor.append(customMask.number) end if otherwise -- < No cursor change > myCursor = 0 end case -- Set the sprite member to the appropriate image if activeFlag then if rollover(spriteNum) then me.showRollover() else mySprite.member = standardImage end if else mySprite.member = inactiveImage end if if buttonID <> "" then --Subscribe to any behaviors that need to (dis)activate the sprite sendAllSprites(#subscribe, buttonID, me) end if end beginSprite -- EVENT HANDLERS -- on mouseEnter(me) if not activeFlag then -- Prevent the mouseEnter from passing to later behaviors on -- the same sprite stopEvent exit end if me.showRollover() end mouseEnter on mouseWithin(me) if not activeFlag then -- Prevent the mouseWithin from passing to later behaviors on -- the same sprite stopEvent exit end if if not myMouseOver then if the mouseUp then me.showRollover() end if end if end mouseWithin on mouseLeave(me) if not activeFlag then -- Prevent the mouseLeave from passing to later behaviors on -- the same sprite stopEvent exit end if me.showRolloff() end mouseLeave on mouseDown(me) if not activeFlag then -- Prevent the mouseDown from passing to later behaviors on -- the same sprite stopEvent exit end if myMouseDown = TRUE mySprite.member = mouseDownImage end mouseDown on mouseUp(me) if not activeFlag then -- Prevent the mouseUp from passing to later behaviors on -- the same sprite stopEvent exit end if myMouseDown = FALSE mySprite.member = rolloverImage -- mouse is still over the button end mouseUp on mouseUpOutside(me) if not activeFlag then -- Prevent the mouseUpOutside from passing to later behaviors on -- the same sprite stopEvent exit end if myMouseDown = FALSE -- mySprite.member = standardImage -- mouse is not over the button end mouseUpOutside -- PRIVATE METHODS -- on showRollover(me) -------------------------------------------------- -- Sent by beginSprite(), mouseEnter(), toggleActive() -- -- * Displays the custom cursor and the rollover member, according -- to whether the user already clicked down on the sprite or not -------------------------------------------------------------------- if the mouseDown and the clickOn <> spriteNum then exit else myMouseOver = TRUE end if if rollover(spriteNum) then if myCursor <> 0 then mySavedCursor = sprite(0).cursor cursor myCursor end if if myMouseDown then mySprite.member = mouseDownImage else if the mouseUp then mySprite.member = rolloverImage end if end if end if end showRollover on showRolloff(me) -------------------------------------------------- -- Sent by mouseLeave(), toggleActive() -- -- Resets the cursor and shows a non-active member -------------------------------------------------------------------- if myCursor <> 0 then cursor mySavedCursor end if if activeFlag then mySprite.member = standardImage else -- The sprite has just been disactivated mySprite.member = inactiveImage end if myMouseOver = FALSE end showRolloff -- UTILITIES -- on addMemberProperties (me, propertiesList) -------------------------- -- Sent by getPropertyDescriptionList() -- -- * Provides property descriptions for the standard, rollover, -- mouseDown and inactive states of the sprite. -------------------------------------------------------------------- defaultMembers = me.getDefaultMembers() propertiesList[ \ #standardImage] = [ \ #comment: "CAST MEMBERS - Standard Cast Member:", \ #format: #graphic, \ #default: defaultMembers[1] \ ] propertiesList[ \ #rolloverImage] = [ \ #comment: "Rollover Cast Member:", \ #format: #graphic, \ #default: defaultMembers[2] \ ] propertiesList[ \ #mouseDownImage] = [ \ #comment: "MouseDown Cast Member:", \ #format: #graphic, \ #default: defaultMembers[3] \ ] propertiesList[ \ #inactiveImage] = [ \ #comment: "Inactive Cast Member:", \ #format: #graphic, \ #default: defaultMembers[4] \ ] end addMemberProperties on getDefaultMembers (me) -------------------------------------------- -- Called by addMemberProperties() -- -- * Returns a list of default members for the Behavior -- Parameters dialog. This assumes that the current member of the -- sprite is the Standard member, and that the other members to -- be associated with the sprite are to be found in the following -- cast member slots. -------------------------------------------------------------------- if not the currentSpriteNum then -- Director is simply recompiling scripts: return dummy -- values return [member 1, member 1, member 1, member 1] else -- Return default members for the Behavior Parameters dialog standardMember = sprite(the currentSpriteNum).member memberType = standardMember.type theNumber = standardMember.number -- Propose the following members in the same cast for the other -- button states... if they are of the same membertype. Otherwise -- propose the standard member rolloverMember = member(theNumber + 1) if rolloverMember.type <> memberType then rolloverMember = standardMember end if mouseDownMember = member(theNumber + 2) if mouseDownMember.type <> memberType then mouseDownMember = standardMember end if inactiveMember = member(theNumber + 3) if inactiveMember.type <> memberType then inactiveMember = standardMember end if return [ \ standardMember, \ rolloverMember, \ mouseDownMember, \ inactiveMember \ ] end if end getDefaultMembers on addCursorProperties (me, propertiesList) -------------------------- -- Sent by getPropertyDescriptionList() -- -- * Provides property descriptions for different cursor types -- according to the the cursor types available. -------------------------------------------------------------------- cursorTypes = [] cursorMembersList = getSuitableMembers(me, #cursor) cursorBitmapsList = getSuitableMembers(me, #bitmap) cursorMasksList = duplicate(cursorBitmapsList) cursorMasksList.addAt(1, "no mask") cursorMembers = cursorMembersList.count() bitmapCursors = cursorBitmapsList.count() if cursorMembers then cursorTypes.append("Cursor member") end if if bitmapCursors then cursorTypes.append("1 bit bitmap") end if if cursorTypes.count() then cursorTypes.addAt(1, "< No cursor change >") cursorTypes.addAt(2, "Built-in cursor") propertiesList[ \ #cursorType] = [ \ #comment: "CURSOR - Use which type of cursor?", \ #format: #string, \ #range: cursorTypes, \ #default: cursorTypes[1] \ ] propertiesList[ \ #builtInCursor] = [ \ #comment: "* Built-in cursor:", \ #format: #cursor, \ #default: 280\ ] else propertiesList[ \ #builtInCursor] = [\ #comment: "CURSOR - Use which cursor?", \ #format: #cursor, \ #default: 280\ ] end if if cursorMembers then propertiesList[ \ #cursorMember] = [ \ #comment: "* Cursor member:", \ #format: #member, \ #range: cursorMembersList, \ #default: cursorMembersList[1] \ ] end if if bitmapCursors then propertiesList[ \ #customCursor] = [ \ #comment: "* 1 bit bitmap (image):", \ #format: #bitmap, \ #range: cursorBitmapsList, \ #default: cursorBitmapsList[1]\ ] propertiesList[ \ #customMask] = [ \ #comment: "1 bit bitmap (mask):", \ #format: #bitmap, \ #range: cursorMasksList, \ #default: cursorMasksList[1]\ ] end if end addCursorProperties on getSuitableMembers (me, memberType) ------------------------------- -- Called by addCursorProperties() -- -- * Returns a list of members of a given type available to the -- current movie. If is #bitmap, the selection is -- limited to 1-bit members whose dimensions are less than 2Ox20 -- pixels. -------------------------------------------------------------------- membersList = [] maxCastLib = the number of castLibs repeat with theCastLib = 1 to maxCastLib maxMember = the number of members of castLib theCastLib repeat with memberNumber = 1 to maxMember theMember = member(memberNumber, theCastLib) if theMember.type = memberType then if memberType = #bitmap then -- Only allow small 1-bit bitmap members if theMember.depth > 1 then next repeat if theMember.width > 20 then next repeat if theMember.height > 20 then next repeat end if if theMember.name = EMPTY then membersList.append(theMember) else membersList.append(theMember.name) end if end if end repeat end repeat return membersList end getSuitableMembers -- BEHAVIOR DESCRIPTION AND PARAMETERS -- on isOKToAttach (me, spriteType, spriteNumber) -- Accept all graphic sprites return (spriteType = #graphic) end isOKToAttach on getPropertyDescriptionList (me) propertiesList = [:] propertiesList[ \ #buttonID] = [ \ #comment: "ID string used to identify this button", \ #format: #string, \ #default: "Button "&the currentSpriteNum \ ] propertiesList[ \ #activeFlag] = [ \ #comment: "Button is initially active?", \ #format: #boolean, \ #default: TRUE \ ] me.addMemberProperties(propertiesList) me.addCursorProperties(propertiesList) return propertiesList end getPropertyDescriptionList on getBehaviorToolTip (me) return \ "Change the sprite's cast member when the"&RETURN&\ "mouse rolls over the current sprite and"&RETURN&\ "when the current sprite is clicked."&RETURN&\ "Rollovers are ignored if the mouse was"&RETURN&\ "clicked down elsewhere." end getBehaviorToolTip on getBehaviorDescription (me) return \ "MOUSE STATES"&RETURN&RETURN&\ "© July 2000, James Newton "&RETURN&RETURN&\ "Change the cursor and the sprite's cast member when the mouse "&\ "rolls over the current sprite, and show a different cast member "&\ "when the current sprite is clicked. Rollovers are ignored if "&\ "the mouse was clicked down elsewhere."&RETURN&RETURN&\ "This behavior only deals with the appearance of the sprite and the cursor: it does not perform any action when the sprite is clicked. Such an action can be provided by a separate behavior on the same sprite. "&RETURN&RETURN&\ "Example subsidiary behavior:"&RETURN&RETURN&\ " on mouseUp(me)"&RETURN&\ " alert ""E&"Ouch, you clicked me!""E&RETURN&\ " end"&RETURN&RETURN&\ "This behavior can be disactivated. If it is, no mouse events will be received by subsequent behaviors on the same sprite. To disactivate the sprite send it a (#toggleActive, FALSE) message. A variety of syntaxes are supported, allowing you to activate and disactivate a whole set of buttons in one sendAllSprites() call. "&RETURN&RETURN&\ "This behavior should always appear first on a sprite: if this is not the case, mouseUp events may not be received if the button is used to jump to a different frame. Also, if the button is to be disactivated, this behavior will prevent mouse events from reaching behaviors which appear later on the scriptInstanceList. "&RETURN&RETURN&\ "PARAMETERS:"&RETURN&\ " * Standard Member:"&RETURN&\ " * Rollover Member: shown when mouse is over sprite"&RETURN&\ " * MouseDown Member: shown when sprite is clicked"&RETURN&\ " * Inactive Member: shown when behavior is disactivated"&\ RETURN&RETURN&\ " * Cursor Type: no change | built-in | #cursor | #bitmap"&RETURN&\ " * Choice of Cursor: according to types available"&RETURN&RETURN&\ "PUBLIC METHODS:"&RETURN&\ " => Toggle the button's acivity on or off"&RETURN&\ " sendSprite , #toggleActive, trueOrFalse"&RETURN&\ " => Get a pointer to the current instance"&RETURN&\ " behaviorRef = sendSprite , #getReference"&\ RETURN&RETURN&\ "Other structures are possible using 'sendAllSprites' or 'call'. "&\ "See the handlers themselves for details." end getBehaviorDescription