3
0
mirror of https://github.com/britzl/monarch.git synced 2025-06-27 10:27:49 +02:00

Added optional callback function when transition is done

This commit is contained in:
Björn Ritzl 2017-09-17 18:55:39 +02:00
parent e5b8f6d031
commit 9be4eeb87c
7 changed files with 46 additions and 22 deletions

View File

@ -35,15 +35,15 @@ The navigation in Monarch is based around a stack of screens. When a screen is s
You show a screen in one of two ways:
1. Post a ````show```` message to the ````screen.script````
2. Call ````monarch.show(screen_id, [clear])````
2. Call ````monarch.show(screen_id, [options], [callback])````
Showing a screen will push it to the top of the stack and trigger an optional transition. The previous screen will be hidden (with an optional transition) unless the screen to be shown is a [popup](#popups).
#### Preventing duplicates in the stack
You can pass an optional ````clear```` flag when showing a screen (either as a second argument to ````monarch.show()```` or in the message). If the clear flag is set Monarch will search the stack for the screen in question. If the screen already exists in the stack and the clear flag is set Monarch will remove all screens between the current top and the screen in question. Example:
You can pass an optional ````clear```` flag when showing a screen (either as a key value pair in the options table when calling ````monarch.show()```` or in the message). If the clear flag is set Monarch will search the stack for the screen in question. If the screen already exists in the stack and the clear flag is set Monarch will remove all screens between the current top and the screen in question. Example:
* Stack is [A, B, C, D] - (D is on top)
* A call to ````monarch.show(B, true)```` is made
* A call to ````monarch.show(B, { clear = true })```` is made
* Stack is [A, B]
### Going back to a previous screen
@ -91,3 +91,6 @@ When a transition is completed it is up to the developer to send a ````transitio
function on_message(self, message_id, message, sender)
self.transition.handle(message_id, message, sender)
end
## Callbacks
Both the ```monarch.show()``` and ```monarch.back()``` functions take an optional callback function that will be invoked when the transition is completed. Note that this will not take into account when custom transitions are completed. The callback will be invoked immediately when the loading and unloading of collections are done and when the internal state of Monarch has completed the navigation.

View File

@ -14,7 +14,9 @@ end
function on_input(self, action_id, action)
if action_id == hash("touch") and action.released then
if gui.pick_node(gui.get_node("win_button"), action.x, action.y) then
monarch.show(hash("menu"), true)
monarch.show(hash("menu"), { clear = true }, function()
print("showing menu done")
end)
end
end
end

View File

@ -14,7 +14,9 @@ end
function on_input(self, action_id, action)
if action_id == hash("touch") and action.released then
if gui.pick_node(gui.get_node("startgame_button"), action.x, action.y) then
monarch.show(hash("popup"))
monarch.show(hash("popup"), nil, function()
print("showing popup done")
end)
end
end
end

View File

@ -18,10 +18,14 @@ function on_input(self, action_id, action)
if action_id == hash("touch") and action.released then
if gui.pick_node(self.ok, action.x, action.y) then
print("ok")
monarch.show(hash("pregame"))
monarch.show(hash("pregame"), nil, function()
print("pregame show done")
end)
elseif gui.pick_node(self.cancel, action.x, action.y) then
print("cancel")
monarch.back()
monarch.back(function()
print("back from popup done")
end)
end
end
end

View File

@ -17,10 +17,14 @@ function on_input(self, action_id, action)
if action_id == hash("touch") and action.released then
if gui.pick_node(self.play, action.x, action.y) then
print("play")
monarch.show(hash("game"))
monarch.show(hash("game"), nil, function()
print("showing game done")
end)
elseif gui.pick_node(self.back, action.x, action.y) then
print("back")
monarch.back()
monarch.back(function()
print("back from pregame done")
end)
end
end
end

View File

@ -41,7 +41,7 @@ function M.unregister(id)
screens[id] = nil
end
local function show_out(screen, next_screen)
local function show_out(screen, next_screen, cb)
local co
co = coroutine.create(function()
screen.co = co
@ -55,11 +55,12 @@ local function show_out(screen, next_screen)
coroutine.yield()
end
screen.co = nil
if cb then cb() end
end)
coroutine.resume(co)
end
local function show_in(screen)
local function show_in(screen, cb)
local co
co = coroutine.create(function()
screen.co = co
@ -73,11 +74,12 @@ local function show_in(screen)
coroutine.yield()
msg.post(screen.script, "acquire_input_focus")
screen.co = nil
if cb then cb() end
end)
coroutine.resume(co)
end
local function back_in(screen, previous_screen)
local function back_in(screen, previous_screen, cb)
local co
co = coroutine.create(function()
screen.co = co
@ -92,11 +94,12 @@ local function back_in(screen, previous_screen)
end
msg.post(screen.script, "acquire_input_focus")
screen.co = nil
if cb then cb() end
end)
coroutine.resume(co)
end
local function back_out(screen)
local function back_out(screen, cb)
local co
co = coroutine.create(function()
screen.co = co
@ -107,6 +110,7 @@ local function back_out(screen)
coroutine.yield()
msg.post(screen.proxy, "unload")
screen.co = nil
if cb then cb() end
end)
coroutine.resume(co)
end
@ -114,8 +118,10 @@ end
--- Show a new screen
-- @param id Id of the screen to show
-- @param clear Set to true if the stack should be cleared down to an existing instance of the screen. Optional
function M.show(id, clear)
-- @param options Table with options when showing the screen (can be nil). Valid values:
-- * clear - Set to true if the stack should be cleared down to an existing instance of the screen
-- @ param cb Optional callback to invoke when screen is shown
function M.show(id, options, cb)
assert(id, "You must provide a screen id")
assert(screens[id], ("There is no screen registered with id %s"):format(tostring(id)))
@ -142,7 +148,7 @@ function M.show(id, clear)
-- already and the clear flag is set then we need
-- to remove every screen on the stack up until and
-- including the screen itself
if clear and in_stack(id) then
if options and options.clear and in_stack(id) then
while true do
if table.remove(stack).id == id then
break
@ -152,19 +158,22 @@ function M.show(id, clear)
end
-- show screen
show_in(screen)
show_in(screen, cb)
end
-- Go back to the previous screen in the stack
function M.back()
-- @param cb Optional callback to invoke when the previous screen is visible again
function M.back(cb)
local screen = table.remove(stack)
if screen then
back_out(screen)
back_out(screen, cb)
local top = stack[#stack]
if top then
back_in(top, screen)
end
elseif cb then
cb()
end
end

View File

@ -24,11 +24,11 @@ end
function on_message(self, message_id, message, sender)
if message_id == hash("show") then
monarch.show(self.screen_id, message.clear)
monarch.show(self.screen_id, { clear = message.clear })
elseif message_id == hash("hide") then
monarch.hide(self.screen_id)
monarch.back()
elseif message_id == hash("back") then
monarch.hide(self.screen_id)
monarch.back()
elseif message_id == hash("transition_show_in")
or message_id == hash("transition_show_out")
or message_id == hash("transition_back_in")