-- Focus Manager. -- @ version 1.0 -- @ Author Luke Wigley luke at meccamedialight com au -- @ Created Tuesday, 19th January 2005, 1:09 pm -- @notes -- -- For an object to be registered with the focusMgr, it needs to add itself -- to the FocusableItems list using #RegisterFocusableItem. -- FocusableItems (widgets etc which can have a 'focus' state) should have the following methods: -- #Focus -- #Blur -- #CanAcceptFocus -- return true or false -- #KeyInput { optional } -- FocusableItems can interact with the FocusMgr using the following public methods: -- #RegisterFocusableItem (FocusableItem) -- #RemoveFocusableItem (FocusableItem) -- #SetFocusTo (registeredFocusableItem) -- #ReleaseFocus () -- release focus from current focussed item -- #ReleaseFocusFrom (registeredFocusableItem) -- Note: When tabbing, this script will ask a widget (by sending #CanAcceptFocus) whether -- it can receive focus before actually assigning focus (this way, a widget that is disabled -- can refuse focus) property FocusableItems -- list of object which can receive focus property CurrentFocus -- object currently with focus -- PUBLIC INTERFACE --------------------------------------- on new(me) -- Overridden; returns the script object -- (this is a singleton obj) this = me.script return this end on Initialise (this) CurrentFocus = 0 FocusableItems = [] the keyDownScript = this.script& ".KeyHandler()" end on Destroy (this) FocusableItems = VOID end on RegisterFocusableItem (this, obj) put #RegisterFocusableItem, obj -- route the call to register through a DOM-specific reference -- to this object (to fix various LDM-related wierdness) m = _movie.stage.movie m.call(#_RegisterFocusableItem, this, obj) end on RemoveFocusableItem (this, obj) this._CheckInit() FocusableItems.deleteOne(obj) if CurrentFocus = obj then if CurrentFocus.ilk = #instance then the keyboardFocusSprite = -1 call(#Blur, [CurrentFocus]) end if CurrentFocus = 0 end if end -- Set focus on SetFocusTo (this, newFocus) -- Tell the obj currently with focus to lose focus, -- and then tell the specified obj to gain focus if CurrentFocus <> newFocus then if CurrentFocus.ilk = #instance then the keyboardFocusSprite = -1 call(#Blur, [CurrentFocus]) end if CurrentFocus = newFocus if CurrentFocus.ilk = #instance then the keyboardFocusSprite = 0 f = call(#Focus, [CurrentFocus]) end if end if end on ReleaseFocus (this) -- Tell the obj currently with focus to lose focus if CurrentFocus.ilk = #instance then the keyboardFocusSprite = -1 call(#Blur, [CurrentFocus]) end if CurrentFocus = 0 end on ReleaseFocusFrom (this, from) -- If the specified obj currently has focus, then -- tell it to lose focus if CurrentFocus = from then if CurrentFocus.ilk = #instance then the keyboardFocusSprite = -1 call(#Blur, [CurrentFocus]) end if CurrentFocus = 0 end if end -- Changing focus using the TAB key on TabForward (this) -- tab forward through the list, giving focus to the next item if FocusableItems.count = 0 then CurrentFocus = 0 exit end if -- which object position currently has focus if CurrentFocus.ilk = #instance then startAt = FocusableItems.getPos(CurrentFocus) else startAt = 0 end if idx = startAt + 1 loopedFlag = 0 repeat while idx <> startAt if idx > FocusableItems.count then if loopedFlag then -- already looped around to the start, so exit exit repeat else -- loop back to the start and keep trying idx = 1 loopedFlag = 1 end if end if if call(#CanAcceptFocus, [FocusableItems[idx]]) then -- found the next object that is able to receive focus newFocus = FocusableItems[idx] this.SetFocusTo(newFocus) exit repeat end if PUT IDX idx = idx + 1 end repeat end on TabBack (this) if FocusableItems.count = 0 then CurrentFocus = 0 exit end if -- which object position currently has focus startAt = FocusableItems.getPos(CurrentFocus) --if (startAt < 1) then startAt = 1 idx = startAt - 1 loopedFlag = 0 repeat while idx <> startAt if idx < 1 then if loopedFlag then -- already looped around to the start, so exit exit repeat else -- loop back to the start and keep trying idx = FocusableItems.count loopedFlag = 1 end if end if if call(#CanAcceptFocus, [FocusableItems[idx]]) then -- found the next object that is able to receive focus newFocus = FocusableItems[idx] this.SetFocusTo(newFocus) exit repeat end if idx = idx - 1 end repeat end on TabFirst (this) if FocusableItems.count = 0 then CurrentFocus = 0 exit end if startAt = 1 idx = startAt + 1 loopedFlag = 0 repeat while idx <> startAt if idx > FocusableItems.count then if loopedFlag then -- already looped around to the start, so exit exit repeat else -- loop back to the start and keep trying idx = 1 loopedFlag = 1 end if end if if call(#CanAcceptFocus, [FocusableItems[idx]]) then -- found the next object that is able to receive focus newFocus = FocusableItems[idx] this.SetFocusTo(newFocus) exit repeat end if idx = idx + 1 end repeat end on TabLast (this) if FocusableItems.count = 0 then CurrentFocus = 0 exit end if -- which object position currently has focus startAt = count(FocusableItems) if (startAt < 1) then startAt = 1 idx = startAt - 1 loopedFlag = 0 repeat while idx <> startAt if idx < 1 then if loopedFlag then -- already looped around to the start, so exit exit repeat else -- loop back to the start and keep trying idx = FocusableItems.count loopedFlag = 1 end if end if if call(#CanAcceptFocus, [FocusableItems[idx]]) then -- found the next object that is able to receive focus newFocus = FocusableItems[idx] this.SetFocusTo(newFocus) exit repeat end if idx = idx - 1 end repeat end -- PRIVATE METHODS --------------------------------------- on _CheckInit (this) -- just check the script has been initialised if voidP(FocusableItems) then this.Initialise() end on _RegisterFocusableItem (this, obj) this._CheckInit() if not (FocusableItems.getOne(obj)) then FocusableItems.append(obj) end -- Sending key events on _SendKeyInput (this, k) if CurrentFocus.ilk = #Instance then call(#FocusKeyInput, [CurrentFocus], k) end if end on KeyHandler (this) k = the keyCode case (k) of 48: -- TAB if NOT(the shiftDown) then this.TabForward() else this.TabBack() end if 36: -- Return this._SendKeyInput(#return) 116: -- Page Up if (the controlDown) then this.TabFirst() end if 121: -- Page Down if (the controlDown) then this.TabLast() end if 123: this._SendKeyInput(#leftArrow) pass 124: this._SendKeyInput(#rightArrow) pass 126: this._SendKeyInput(#UpArrow) pass 125: this._SendKeyInput(#DownArrow) pass otherwise pass end case end