How to get the current scene, even if it is an overlay?

Dear Corona,

I am using the storyboard api to figure out which scene is currently displayed like this:

local currentSceneName = storyboard.getCurrentSceneName() swl.printInfo("The current scene is: " .. currentSceneName, fileName, methodName) local currentScene = storyboard.getScene(currentSceneName)

However, if an overlay is displayed using storyboard.showOverlay(…), the above code will still return the original scene. For example:

  1. Load a scene, menu.lua

  2. From menu.lua scene show an myOverlay overlay

  3. Push the hardware back button

  4. The code in main.lua to get the current scene will still retrieve the menu scene not the myOverlay scene. How can I retrieve the the current scene including overlays?

main.lua

local storyboard = require "storyboard" -- setup hardware back key listener local function onKeyEvent( event ) -- Handle back key if (event.keyName == "back") and (event.phase == "up") and (system.getInfo("platformName") == "Android") then local currentSceneName = storyboard.getCurrentSceneName() local currentScene = storyboard.getScene(currentSceneName) if currentScene ~= nil then -- Each scene is coded with its own function for handling the back button, including overlays. if (currentScene.onBackKey and type(currentScene.onBackKey)=="function") then return currentScene:onBackKey(event) else return true end else return false end end -- Return false to indicate that this app is \*not\* overriding the received key. -- This lets the operating system execute its default handling of this key. return false end Runtime:addEventListener( "key", onKeyEvent ) storyboard.goToScene("menu")

menu.lua

... -- Called immediately after scene has moved onscreen: function scene:enterScene( event ) storyboard.showOverlay( "myOverlay", { time = 250, effect = "fromTop", isModal = true } ) end function scene:onBackKey(event) -- handle the back key on this scene ... return true end ...

myOverlay.lua

... function scene:onBackKey(event) -- handle the back key on this scene, which happens to be an overlay ... return true end ...

Thanks!

that is very similar to how i handle the back button… and one of the reasons I use my own customized version of the storyboard source.  then it’s easy:

--- Return the currently active overlay -- (exposes the local currentOverlay variable) -- @return the scene object of the currently active overlay, or nil if no overlay is currently active function storyboard.getCurrentOverlay()   return currentOverlay end

or maybe, for convenience:

--- Return the top-most scene object, whether an overlay or a base scene -- @return the scene object of the top-most scene function storyboard.getTopmostSceneObject()  return currentOverlay or (currentModule and storyboard.scenes[currentModule]) end

[edit:  fixed some typos, just use for ideas, may not run exactly as written]

Thanks for the reply dave!

As of right now I’m not brave enough to use a custom version of the corona source, but maybe the corona guys will take this as a hint for the next version?  :smiley:

For now as a work around, I changed my key handler to this (note swl.printInfo() is just a custom logging mechanism I wrote):

-- setup hardware back key listener local function onKeyEvent( event ) local methodName = "onKeyEvent()" -- Print which key was pressed down/up to the log. swl.printInfo("Key '" .. event.keyName .. "' was pressed " .. event.phase, fileName, methodName) -- Handle back key if (event.keyName == "back") and (event.phase == "up") and (system.getInfo("platformName") == "Android") then local currentSceneName = storyboard.getCurrentSceneName() swl.printInfo("The current scene is: " .. currentSceneName, fileName, methodName) -- Get the current scene object local currentScene = storyboard.getScene(currentSceneName) if currentScene == nil then swl.printInfo("Couldn't get the current scene object!", fileName, methodName) return false end -- Check for an active overlay if currentScene.currentOverlaySceneName ~= nil then swl.printInfo("The active overlay scene is: " .. currentScene.currentOverlaySceneName, fileName, methodName) currentScene = storyboard.getScene(currentScene.currentOverlaySceneName) end if currentScene == nil then swl.printInfo("Couldn't get the current scene overlay object!", fileName, methodName) return false end if (currentScene.onBackKey and type(currentScene.onBackKey)=="function") then swl.printInfo("Calling the scene's onBackKey method...", fileName, methodName) return currentScene:onBackKey(event) else swl.printInfo("No scene onBackKey() handler, returning true without doing anything.", fileName, methodName) return true end end -- Return false to indicate that this app is \*not\* overriding the received key. -- This lets the operating system execute its default handling of this key. swl.printInfo("Default key handler: returning false", fileName, methodName) return false end Runtime:addEventListener( "key", onKeyEvent )

And in any scene which uses an overlay, I added this tracking logic:

-- the following event is dispatched once the overlay is in place function scene:overlayBegan( event ) local methodName = "overlayBegan()" swl.printInfo("Showing overlay: " .. event.sceneName, fileName, methodName ) scene.currentOverlaySceneName = event.sceneName end -- the following event is dispatched once overlay is removed function scene:overlayEnded( event ) local methodName = "overlayEnded()" swl.printInfo("Overlay removed: " .. event.sceneName, fileName, methodName) scene.currentOverlaySceneName = nil end scene:addEventListener( "overlayBegan" ) scene:addEventListener( "overlayEnded" )

that is very similar to how i handle the back button… and one of the reasons I use my own customized version of the storyboard source.  then it’s easy:

--- Return the currently active overlay -- (exposes the local currentOverlay variable) -- @return the scene object of the currently active overlay, or nil if no overlay is currently active function storyboard.getCurrentOverlay()   return currentOverlay end

or maybe, for convenience:

--- Return the top-most scene object, whether an overlay or a base scene -- @return the scene object of the top-most scene function storyboard.getTopmostSceneObject()  return currentOverlay or (currentModule and storyboard.scenes[currentModule]) end

[edit:  fixed some typos, just use for ideas, may not run exactly as written]

Thanks for the reply dave!

As of right now I’m not brave enough to use a custom version of the corona source, but maybe the corona guys will take this as a hint for the next version?  :smiley:

For now as a work around, I changed my key handler to this (note swl.printInfo() is just a custom logging mechanism I wrote):

-- setup hardware back key listener local function onKeyEvent( event ) local methodName = "onKeyEvent()" -- Print which key was pressed down/up to the log. swl.printInfo("Key '" .. event.keyName .. "' was pressed " .. event.phase, fileName, methodName) -- Handle back key if (event.keyName == "back") and (event.phase == "up") and (system.getInfo("platformName") == "Android") then local currentSceneName = storyboard.getCurrentSceneName() swl.printInfo("The current scene is: " .. currentSceneName, fileName, methodName) -- Get the current scene object local currentScene = storyboard.getScene(currentSceneName) if currentScene == nil then swl.printInfo("Couldn't get the current scene object!", fileName, methodName) return false end -- Check for an active overlay if currentScene.currentOverlaySceneName ~= nil then swl.printInfo("The active overlay scene is: " .. currentScene.currentOverlaySceneName, fileName, methodName) currentScene = storyboard.getScene(currentScene.currentOverlaySceneName) end if currentScene == nil then swl.printInfo("Couldn't get the current scene overlay object!", fileName, methodName) return false end if (currentScene.onBackKey and type(currentScene.onBackKey)=="function") then swl.printInfo("Calling the scene's onBackKey method...", fileName, methodName) return currentScene:onBackKey(event) else swl.printInfo("No scene onBackKey() handler, returning true without doing anything.", fileName, methodName) return true end end -- Return false to indicate that this app is \*not\* overriding the received key. -- This lets the operating system execute its default handling of this key. swl.printInfo("Default key handler: returning false", fileName, methodName) return false end Runtime:addEventListener( "key", onKeyEvent )

And in any scene which uses an overlay, I added this tracking logic:

-- the following event is dispatched once the overlay is in place function scene:overlayBegan( event ) local methodName = "overlayBegan()" swl.printInfo("Showing overlay: " .. event.sceneName, fileName, methodName ) scene.currentOverlaySceneName = event.sceneName end -- the following event is dispatched once overlay is removed function scene:overlayEnded( event ) local methodName = "overlayEnded()" swl.printInfo("Overlay removed: " .. event.sceneName, fileName, methodName) scene.currentOverlaySceneName = nil end scene:addEventListener( "overlayBegan" ) scene:addEventListener( "overlayEnded" )