-- MUI wrapper -- @Version 1.0.0 -- @Description -- One annoying thing about the MUI Xtra is that you cannot specify a target or listener -- for MUI callbacks - it has to be a moviescript function. This script is a wrapper -- for the Xtra that lets you specify a callback target. To Destroy the object, call the -- Destroy method before clearing references. In all other regards, use this script -- as if it were the Xtra. -- @Notes -- This script will create a temporary moviescript called "MUI.Proxy.TEMP", and stash a reference -- to it. -- @Dependencies -- Xtra("MUI") -- Instance Props property ancestor, Callback, Target -- Class Props property __CalllbackMap -- PUBLIC METHODS ----------------------------------------------- on new (me) -- create a new instance of the script. For the most part, this can be -- treated as if it were an instance of the Xtra (except you should -- call the destroy method when finished) me._Initialise() return me end on Destroy(me) -- Destroy the instance and release temp scripts script("MUI").__ReleaseTempScript(me) ancestor = VOID end on initialize (me, plist) -- ovveride the xtra method by grabbing the callback and target -- properties and initialsing the Xtra me.Callback = pList.windowPropList[#Callback] if pList.windowPropList[#Target].ilk = #instance then me.Target = pList.windowPropList[#Target] pList.deleteProp(#Target) end if pList.windowPropList[#Callback] = script("MUI").__BindCallback(me) ancestor.initialize(plist) end -- PRIVATE INSTANCE METHODS ----------------------------------------------- on _Initialise (me) me.ancestor = xtra("MUI").new() end on _HandleCallback(this, event, widgetNumber, widgetProps ) -- this method is called by the temporary movie script object -- used to capture the Xtra's callback, if Target.ilk = #instance then call(Callback, Target, event, widgetNumber, widgetProps ) else put "No target" end if end -- PRIVATE SCRIPT METHODS ----------------------------------------------- -- These methods are called using a reference to the script object -- rather than the instance. This means instances can share common data on __BindCallback (this, obj) -- Create a temporary movie-level function to make a callback -- to the specified object. -- First, check whether we have a map (proplist mapping callbacks to targets) if this.__CalllbackMap.ilk <> #propList then this.__CalllbackMap = [:] end if -- check if we need to make the temp movie script tmp = member("MUI.Proxy.TEMP") if tmp.ilk <> #member then tmp = new(#Script) tmp.scriptType = #movie tmp.name = "MUI.Proxy.TEMP" end if -- create a unique identifier for the object wanting to be bound Nonce = this._GetUniqueIdFromInstance(obj) -- have we already bound this object? cbmap = this.__CalllbackMap.getAProp(Nonce) if cbmap.ilk <> #propList then -- haven't already got a callback map, so -- create a unique function for the callback CallBackHandler = "MUIWrapper_CallbackProxy_"&Nonce -- make the temporary script txt = "" txt = txt & "on " & CallBackHandler & "( event, widgetNumber, widgetProps )" & return txt = txt & " Target = script(""E&"MUI""E&").__GETMUIInstanceTarget("& QUOTE & Nonce & QUOTE & ")" & return txt = txt & "Target._HandleCallback( event, widgetNumber, widgetProps )" & return txt = txt & "end" & return tmp.scriptText = txt -- create a reference to the script object (this will keep -- the script object 'alive' even if the script cast member -- is changed or deleted tmpObj = script("MUI.Proxy.TEMP") this.__CalllbackMap.addProp(Nonce, [#movieScriptObj: tmpObj, #CallbackTarget: obj]) end if -- return the name of the callback handler created specifically -- for this object we have 'bound' return CallBackHandler end on __GETMUIInstanceTarget (this, id) -- Return the target specified by id cb = this.__CalllbackMap.getAProp(id) return cb.CallbackTarget end on __ReleaseTempScript (this, id) -- release any temp script object s put #__ReleaseTempScript, this, id, this.__CalllbackMap if id.ilk = #Instance then id = this._GetUniqueIdFromInstance(id) if this.__CalllbackMap.ilk = #propList then if this.__CalllbackMap.GetAProp(id ) <> VOID then this.__CalllbackMap.deleteProp(id) else put (this && "warning: Cannot locate object with id " & id) end if end on __ReleaseTempScripts (this) -- release any temp script objects if this.__CalllbackMap.ilk = #propList then this.__CalllbackMap = [:] end if end on _GetUniqueIdFromInstance (this, i) if i.ilk <> #instance then return "" id = string(i).word[4] return id.char[1..id.length-1] end