property spriteNum, pRot, pCircle, pMouseV, pMouseH, pCenter, pCenterV, pCount, pRight, pLeft, pCount2 property pDial360, pDial255, pDial100 -- dial limit values property pDialValue -- the value returned from the dial property pUseTextMember -- display dial value in a text cast member? property pTextMember -- the text member to use to display the dial's output -- -- This behavior allows a sprite to be moved like a rotating dial. -- Note: If pLeft and pRight are set to 0 (the default), the dial may be spun around indefinitely. -- You can use the value of the text member to set the properties of other sprites, sound volume, etc. -- Initial behavior by Bernhard Gaul - 05/31/99 -- Reworked and updated for Director 11.5 by Ken Loge - http://diginoodles.com - 04-28-10 -- on getPropertyDescriptionList dialList = [:] addProp dialList, #pLeft, [#comment: "Left rotation limit:", #format: #float, #default: 0] addProp dialList, #pRight, [#comment: "Right rotation limit:", #format: #float, #default: 1] addProp dialList, #pDial360, [#comment: "Output range = 0-360", #format: #boolean, #default: 1] addProp dialList, #pDial255, [#comment: "Output range = 0-255", #format: #boolean, #default: 0] addProp dialList, #pDial100, [#comment: "Output range = 0-100", #format: #boolean, #default: 0] addProp dialList, #pUseTextMember, [#comment: "Display value in text cast member?", #format: #boolean, #default: 1] addProp dialList, #pTextMember, [#comment: "Display value in which text cast member?", #format: #text, #default: "info"] return dialList end on beginSprite me -- assign sprite spriteNum = sprite(me.spriteNum) -- make sure that the registration point is centered member(sprite(spriteNum).member).centerRegPoint = true -- make sure that initial rotation is 0 sprite(spriteNum).rotation = 0 -- find horizontal center of sprite as value relative to stageleft pCenter = ((sprite(spriteNum).rect[3] - sprite(spriteNum).rect[1]) / 2) + sprite(spriteNum).rect[1] -- find vertical center of sprite as value relative to stagetop pCenterV = ((sprite(spriteNum).rect[4] - sprite(spriteNum).rect[2]) / 2) + sprite(spriteNum).rect[2] -- create a rotation factor in relation to the height of the sprite pRot = float(180) / sprite(spriteNum).height -- defining radius for inner circle around which the sprite is spun -- relative to the height of sprite pCircle = sprite(spriteNum).height / 6 if pLeft < 0 then alert "Error: Please use only positive values for the up properties." if pRight < 0 then alert "Error: Please use only positive values for the up properties." end on mouseDown me -- retrieve initial mouse position when action starts pMouseV = _mouse.mouseV pMouseH = _mouse.mouseH end on exitFrame me -- stop sprite from moving beyond the limit pCount2 = float(sprite(spriteNum).rotation / 360) if pRight = 0 AND pLeft = 0 then dial(me) else if pCount2 > pRight then rightLimit(me) else if pCount2 < 0 - pLeft then leftLimit(me) else dial(me) end if end if end if -- make sure that the value stays between 0 and 360 -- if you set both parameters to 0 if pRight = 0 AND pLeft = 0 then pCount = integer((sprite(spriteNum).rotation - 180) / 360) if pDialValue > 360 then pDialValue = pDialValue - (360 * pCount) else if pDialValue < 0 then pDialValue = (0 - 360 * pCount) + pDialValue else nothing end if end if else -- make sure that the value doesn't get above the limit even if the -- sprite is swung a little bit beyond it if pDialValue > pDialValue * 360 then pDialValue = pDialValue * 360 else if pDialValue < 0 - pLeft * 360 then pDialValue = 0 - pLeft * 360 end if end if -- update the variables for the mouse position to be able -- to detect the mouse movement between this -- exitFrame execution and the next one pMouseV = _mouse.mouseV pMouseH = _mouse.mouseH -- make sure the dial snaps back if it was swung beyond the limit if pRight = 0 and pLeft = 0 then nothing else if the rollover of sprite(spriteNum) = 0 then if pCount2 > pRight then sprite(spriteNum).rotation = 360 * pRight else if pCount2 < 0 - pLeft then sprite(spriteNum).rotation = 0 - 360 * pLeft else nothing end if end if end if end if -- retrieve rotation angle of the dial as global variable pDialValue = sprite(spriteNum).rotation end -- display values in a text member and set the output range from the dial on enterFrame me -- display value only if text member option is TRUE if pUseTextMember = TRUE then -- convert to user-defined value range if pDial360 = TRUE then pDialValue = pDialValue else if pDial255 = TRUE then pDialValue = pDialValue * .7083 else if pDial100 = TRUE then pDialValue = pDialValue * .27777 else -- if more than one option is set, default to 0-360 range pDialValue = pDialValue end if -- show the dial value in the text member member(pTextMember).text = string(integer(pDialValue)) end if end on dial me -- this handler syncronizes the rotation with the mouse movement if sprite(spriteNum).rollover then if _mouse.stillDown then -- detect where mouse is relative to inner circle if _mouse.mouseH - pCenter > pCircle then firstHalf(me) else if _mouse.mouseH - pCenter < - pCircle then secondHalf(me) else if _mouse.mouseV - pCenterV > 0 then leftRight(me) else rightLeft(me) end if end if end if end if end if end on firstHalf me sprite(spriteNum).rotation = sprite(spriteNum).rotation + (_mouse.mouseV - pMouseV) * pRot end on secondHalf me sprite(spriteNum).rotation = sprite(spriteNum).rotation + (pMouseV - _mouse.mouseV) * pRot end on leftRight me sprite(spriteNum).rotation = sprite(spriteNum).rotation + (pMouseH - _mouse.mouseH) * pRot end on rightLeft me sprite(spriteNum).rotation = sprite(spriteNum).rotation + (_mouse.mouseH - pMouseH) * pRot end on rightLimit me -- stop movement if limit is reached if _mouse.mouseH - pCenter > pCircle AND (_mouse.mouseV - pMouseV) > 0 then nothing else if _mouse.mouseH - pCenter < 0 - pCircle AND (_mouse.mouseV - pMouseV) < 0 then nothing else if _mouse.mouseV - pCenterV > 0 AND _mouse.mouseH - pCenter < pCircle AND (pMouseH - _mouse.mouseH) > 0 then nothing else if _mouse.mouseV - pCenterV < 0 AND (pCenter - _mouse.mouseH) < pCircle AND (pMouseH - _mouse.mouseH) < 0 then nothing else dial(me) end if end if end if end if end on leftLimit me -- stop movement if limit is reached if _mouse.mouseH - pCenter > pCircle AND (_mouse.mouseV - pMouseV) < 0 then nothing else if _mouse.mouseH - pCenter < 0 - pCircle AND (_mouse.mouseV - pMouseV) > 0 then nothing else if _mouse.mouseV - pCenterV > 0 AND _mouse.mouseH - pCenter < pCircle AND (pMouseH - _mouse.mouseH) < 0 then nothing else if _mouse.mouseV - pCenterV < 0 AND (pCenter - _mouse.mouseH) < pCircle AND (pMouseH - _mouse.mouseH) > 0 then nothing else dial(me) end if end if end if end if end on mouseUp me -- make sure the dial snaps back if it was swung beyond the limit if pRight = 0 AND pLeft = 0 then nothing else if pCount2 > pRight then sprite(spriteNum).rotation = 360 * pRight else if pCount2 < 0 - pLeft then sprite(spriteNum).rotation = 0 - 360 * pLeft else nothing end if end if end if end on mouseUpOutside me -- make sure the dial snaps back if it was swung beyond the limit if pRight = 0 AND pLeft = 0 then nothing else if pCount2 > pRight then sprite(spriteNum).rotation = 360 * pRight else if pCount2 < 0 - pLeft then sprite(spriteNum).rotation = 0 - 360 * pLeft else nothing end if end if end if end