Scrollbar Behavior
From Directorforum Collaboration Wiki
Contents |
Description
A scroll bar behavior that emulates the scroll bar object found in the discontinued OSControls Xtra.
Director MX 2004, Director 11
Example
Files
- Director 10 Source - Media:Astro_scrollbar_control_d10.dir
- Director 11 Source - Media:Astro_scrollbar_control.dir
- Image Template - Media:Scrollbar_layout.png (Fireworks CS3 with layers)
Lingo
-- AstrO Controls :: Scrollbar -- version 1.0b8-19Jun08 -- Created by Toby De Ieso -- Modified by Toby De Ieso -- Release Notes (1.0b8-19Jun08): -- * Fixed scrollbar displaying enabled state on startup when linked to a member and -- scrollMember.height is less than scrollMember.pageHeight -- Release Notes (1.0b7-19Jun08): -- * Fixed value becoming a negative in certain situations (caused display issues with #field members) -- * Fixed an execution order bug which would send an update command before setting the scrollTop value -- of a linked field/text member -- * Up and down functions now scroll by line when a field/text member is selected -- (the amount of lines scrolled can be set by pScrollAmount) property pSprite property pMember property pWidth property pHeight property pCurrentStates property pImageMapMember property pImage property pUseScrollMember property pMinBarHeight property pActiveMap property pMouseDown property pScrollAmount property pTimer property pClickOffset property pBackHeight property pBarHeight property pBackHeightOffset property pObjectList property pSizeList property pStateList property enabled property groupId property maxValue property orientation property scrollMember property value property viewSize property pPointItem property pRectOffset property pQuadPositions property pQuadOffset on getPropertyDescriptionList me, descriptionList descriptionList = [:] descriptionList.addProp(#enabled, [#comment:"enabled",#format:#boolean,#default:TRUE]) descriptionList.addProp(#orientation, [#comment:"orientation",#format:#symbol,#default:#vertical,#range:[#vertical,#horizontal]]) descriptionList.addProp(#value, [#comment:"value",#format:#integer,#default:0]) descriptionList.addProp(#maxValue, [#comment:"maxValue",#format:#integer,#default:100]) descriptionList.addProp(#viewSize, [#comment:"viewSize",#format:#integer,#default:50]) descriptionList.addProp(#scrollMember, [#comment:"scrollMember",#format:#member,#default:1]) descriptionList.addProp(#pUseScrollMember, [#comment:"Use scrollMember",#format:#boolean,#default:FALSE]) descriptionList.addProp(#pHeight, [#comment:"Height/Width",#format:#integer,#default:150]) descriptionList.addProp(#pImageMapMember, [#comment:"ImageMapMember",#format:#bitmap,#default:1]) descriptionList.addProp(#pScrollAmount, [#comment:"pScrollAmount",#format:#integer,#default:1]) return descriptionList end on isOKToAttach me, tSpriteType, tSpriteNum tReturn = FALSE if sprite(tSpriteNum).member.type = #bitmap then tReturn = TRUE return tReturn end on beginSprite me pSprite = sprite(me.spriteNum) pMember = pSprite.member pMinBarHeight = 16 pBackHeight = 0 pBarHeight = 0 pBackHeightOffset = 0 pWidth = 16 pCurrentStates = [#up:#normal,#down:#normal,#bar:#normal,#background:#normal] pMouseDown = #none pTimer = 0 pClickOffset = 0 pPointItem = [#horizontal:1,#vertical:2] pQuadPositions = [[1,2],[3,2],[3,4],[1,4]] pRectOffset = [1,2,3,4] pQuadOffset = [1,2,3,4] groupId = 0 pObjectList = [:] pObjectList.addProp(#up,rect(0, 0, 16, 16)) pObjectList.addProp(#bar_top,rect(0, 16, 16, 20)) pObjectList.addProp(#bar, rect(0, 20, 16, 36)) pObjectList.addProp(#bar_bottom,rect(0, 36, 16, 40)) pObjectList.addProp(#bar_overlay,rect(0, 40, 16, 56)) pObjectList.addProp(#background,rect(0, 56, 16, 72)) pObjectList.addProp(#down,rect(0, 72, 16, 88)) pSizeList = [:] repeat with i = 1 to pObjectList.count pSizeList.addProp(pObjectList.getPropAt(i),rect(0,0,pObjectList[i].width,pObjectList[i].height)) end repeat pStateList = [#normal:0,#over:0,#down:0,#disabled:0] repeat with i = 1 to pStateList.count pStateList[i] = rect(point((i - 1) * pWidth,0),point((i - 1) * pWidth,0)) end repeat if pUseScrollMember then if scrollMember.height > scrollMember.pageHeight then scrollMember.scrollTop = value maxValue = scrollMember.height viewSize = scrollMember.pageHeight else enabled = FALSE end if end if me.resetControl() end on resetControl(me) if orientation = #vertical then pRectOffset = [1,2,3,4] pQuadOffset = [1,2,3,4] pImage = image(pWidth,pHeight,32) else pRectOffset = [2,1,4,3] pQuadOffset = [1,4,3,2] pImage = image(pHeight,pWidth,32) end if pActiveMap = [:] pActiveMap.addProp(#up,me.remapRect(pSizeList.up)) pActiveMap.addProp(#down,me.remapRect(pSizeList.down + rect(0,pHeight - pSizeList.down.height,0,pHeight - pSizeList.down.height))) pActiveMap.addProp(#bar,rect(0,0,0,0)) pActiveMap.addProp(#background,me.remapRect(rect(0,pSizeList.up.height,pWidth,pHeight - pSizeList.down.height))) me.updateDisplay() end on remapRect(me,tRect) tRect = rect(tRect[pRectOffset[1]],tRect[pRectOffset[2]],tRect[pRectOffset[3]],tRect[pRectOffset[4]]) return tRect end on createQuad(me,tRect) tQuad = [] repeat with i = 1 to 4 tQuad.append( point(tRect[pQuadPositions[pQuadOffset[i]][1]],tRect[pQuadPositions[pQuadOffset[i]][2]]) ) end repeat return tQuad end on updateDisplay(me) if enabled then -- Copy Background then Up and Down buttons pImage.copyPixels(pImageMapMember.image, me.createQuad(pActiveMap.background), pObjectList.background + pStateList[pCurrentStates.background]) pImage.copyPixels(pImageMapMember.image, me.createQuad(pActiveMap.up), pObjectList.up + pStateList[pCurrentStates.up]) pImage.copyPixels(pImageMapMember.image, me.createQuad(pActiveMap.down), pObjectList.down + pStateList[pCurrentStates.down]) -- Copy bar/slider me.calculateBar() tBarLoc = (pBackHeight * (value/maxValue.float)).integer + pSizeList.up.height - (pBackHeightOffset * (value/maxValue.float)).integer tBarLoc = rect(0,tBarLoc,0,tBarLoc) pActiveMap.bar = me.remapRect(tBarLoc + rect(0,0,pWidth,pBarHeight)) tOverLayOffset = ((pBarHeight / 2.0) - (pSizeList.bar_overlay.height / 2.0)).integer pImage.copyPixels(pImageMapMember.image, me.createQuad(me.remapRect(tBarLoc + rect(0,pSizeList.bar_top.height,pWidth,pBarHeight - pSizeList.bar_bottom.height))), pObjectList.bar + pStateList[pCurrentStates.bar]) pImage.copyPixels(pImageMapMember.image, me.createQuad(me.remapRect(tBarLoc + pSizeList.bar_top)),pObjectList.bar_top + pStateList[pCurrentStates.bar]) pImage.copyPixels(pImageMapMember.image, me.createQuad(me.remapRect(tBarLoc + pSizeList.bar_bottom + rect(0,pBarHeight - pSizeList.bar_bottom.height,0,pBarHeight - pSizeList.bar_bottom.height))), pObjectList.bar_bottom + pStateList[pCurrentStates.bar]) pImage.copyPixels(pImageMapMember.image, me.createQuad(me.remapRect(tBarLoc + rect(0,tOverLayOffset,0,tOverLayOffset) + pSizeList.bar_overlay)),pObjectList.bar_overlay + pStateList[pCurrentStates.bar]) else -- Quick draw for disabled scrollbar pImage.copyPixels(pImageMapMember.image, me.createQuad(pActiveMap.background), pObjectList.background + pStateList.disabled) pImage.copyPixels(pImageMapMember.image, me.createQuad(pActiveMap.up), pObjectList.up + pStateList.disabled) pImage.copyPixels(pImageMapMember.image, me.createQuad(pActiveMap.down), pObjectList.down + pStateList.disabled) end if pMember.image = pImage.duplicate() pMember.regPoint = point(0,0) end on checkMouse(me,tLoc,tIgnoreList) tFound = #none repeat with i = 1 to pActiveMap.count if tIgnoreList.getPos(pActiveMap.getPropAt(i)) = 0 then if tLoc.inside(pActiveMap[i]) then tFound = pActiveMap.getPropAt(i) exit repeat end if end if end repeat return tFound end on calculateBar(me) pBackHeight = pHeight - (pSizeList.up.height + pSizeList.down.height) tRealHeight = (pBackHeight * (viewSize/maxValue.float)).integer pBarHeight = max( pMinBarHeight, tRealHeight ) pBackHeightOffset = pBarHeight - tRealHeight end on activateButton(me,tButton,tState) pCurrentStates = [#up:#normal,#down:#normal,#bar:#normal,#background:#normal] case pMouseDown of #up,#down,#bar: pCurrentStates[pMouseDown] = #down #background: nothing otherwise: if tButton <> #none then pCurrentStates[tButton] = tState end case end on updateValue(me,tSection) if voidP(tSection) then tSection = pMouseDown value = min(max(0,maxValue - viewSize),max(0,value.integer)) if pUseScrollMember then case tSection of #up: scrollMember.scrollbyline(-pScrollAmount) value = scrollMember.scrollTop #down: scrollMember.scrollbyline(pScrollAmount) value = scrollMember.scrollTop otherwise: if scrollMember.scrollTop <> value then scrollMember.scrollTop = value end case end if end on runScrollButtons(me,tDelay) tOldValue = value tUpdate = #none case pMouseDown of #up: value = value - pScrollAmount tUpdate = #up pTimer = _system.milliseconds + tDelay #down: value = value + pScrollAmount tUpdate = #down pTimer = _system.milliseconds + tDelay #background: tLoc = _mouse.mouseLoc - pSprite.loc if not(tLoc.inside(pActiveMap.bar)) and tLoc.inside(pActiveMap.background) then tBarLoc = (pBackHeight * (value/maxValue.float)).integer + pSizeList.up.height - (pBackHeightOffset * (value/maxValue.float)).integer if tBarLoc > (_mouse.mouseLoc[pPointItem[orientation]] - (pSprite.loc[pPointItem[orientation]] + pSizeList.up.height)) then value = value - viewSize tUpdate = #pageUp else value = value + viewSize tUpdate = #pageDown end if pTimer = _system.milliseconds + tDelay end if #bar: me.calculateBar() tLocY = (_mouse.mouseLoc[pPointItem[orientation]] - pClickOffset) - (pSprite.loc[pPointItem[orientation]] + pSizeList.up.height) tLocY = tLocY + ((tLocY / pBackHeight.float) * pBackHeightOffset) value = ((tLocY / pBackHeight.float) * maxValue).integer tUpdate = #thumb end case me.updateValue() if value <> tOldValue then if tUpdate <> #none then _movie.sendSprite(me.spriteNum,#update,tUpdate) end if end on click(me,tSection) case tSection of #up: value = value - pScrollAmount #down: value = value + pScrollAmount #pageUp: value = value - viewSize #pageDown: value = value + viewSize end case me.updateValue(tSection) me.updateDisplay() end on setGroupProp(me,tProperty,tValue) trace("Sorry but this method is not working") end on showProps(me) trace("Sorry but this method is not working") end on enterFrame me if pUseScrollMember then if value <> scrollMember.scrollTop then value = scrollMember.scrollTop if maxValue <> scrollMember.height then maxValue = scrollMember.height if viewSize <> scrollMember.pageHeight then viewSize = scrollMember.pageHeight enabled = (maxValue > viewSize) end if if (_system.milliseconds > pTimer) or (pMouseDown = #bar) then me.runScrollButtons(33) tButton = me.checkMouse(_mouse.mouseLoc - pSprite.loc,[#background]) me.activateButton(tButton,[#over,#down][_mouse.stillDown + 1]) me.updateDisplay() end on mouseDown me pMouseDown = me.checkMouse(_mouse.mouseLoc - pSprite.loc,[]) pClickOffset = _mouse.mouseLoc[pPointItem[orientation]] - (pSprite.loc[pPointItem[orientation]] + pActiveMap.bar[pPointItem[orientation]]) me.runScrollButtons(250) end on mouseUp me pMouseDown = #none end on mouseUpOutside me pMouseDown = #none end
