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

Implement monarch.replace() (#61)

This commit is contained in:
Marius Petcu 2020-05-20 16:36:29 +03:00 committed by GitHub
parent c7fb2ba646
commit 4ad86d41fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 0 deletions

View File

@ -319,6 +319,10 @@ The options table can contain the following fields:
* ```reload``` (boolean) - If the `reload` flag is set Monarch will reload the collection proxy if it's already loaded (this can happen if the previous screen was a popup).
* ```no_stack``` (boolean) - If the `no_stack` flag is set Monarch will load the screen without adding it to the screen stack.
* ```sequential``` (boolean) - If the `sequential` flag is set Monarch will start loading the screen only after the previous screen finished transitioning out.
* ```pop``` (number) - If `pop` is set to a number, Monarch will pop that number of screens from the stack before adding the new one.
### monarch.replace(screen_id, [options], [data], [callback])
Replace the top of the stack with a new screen. Equivalent to calling `monarch.show()` with `pop = 1`. It takes the same parameters as `monarch.show()`.
### monarch.hide(screen_id, [callback])

View File

@ -69,6 +69,16 @@ local function pcallfn(fn, ...)
end
end
local function assign(to, from)
if not from then
return to
end
for k, v in pairs(from) do
to[k] = v
end
return to
end
local function cowait(delay)
local co = coroutine.running()
assert(co, "You must run this from within a coroutine")
@ -649,6 +659,8 @@ end
-- This would be the case if doing a show() from a popup on the screen just below the popup.
-- * sequential - Set to true to wait for the previous screen to show itself out before starting the
-- show in transition even when transitioning to a different scene ID.
-- * no_stack - Set to true to load the screen without adding it to the screen stack.
-- * pop - The number of screens to pop from the stack before adding the new one.
-- @param data (*) - Optional data to set on the screen. Can be retrieved by the data() function
-- @param cb (function) - Optional callback to invoke when screen is shown
function M.show(id, options, data, cb)
@ -712,6 +724,14 @@ function M.show(id, options, data, cb)
end
end
if options and options.pop then
for i = 1, options.pop do
local stack_top = #stack
if stack_top < 1 then break end
stack[stack_top] = nil
end
end
-- show screen, wait until preloaded if it is already preloading
-- this can typpically happen if you do a show() on app start for a
-- screen that has Preload set to true
@ -734,6 +754,20 @@ function M.show(id, options, data, cb)
end
--- Replace the top of the stack with a new screen
-- @param id (string|hash) - Id of the screen to show
-- @param options (table) - 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
-- * reload - Set to true if screen should be reloaded if it already exists in the stack and is loaded.
-- This would be the case if doing a show() from a popup on the screen just below the popup.
-- * no_stack - Set to true to load the screen without adding it to the screen stack.
-- @param data (*) - Optional data to set on the screen. Can be retrieved by the data() function
-- @param cb (function) - Optional callback to invoke when screen is shown
function M.replace(id, options, data, cb)
return M.show(id, assign({ pop = 1 }, options), data, cb)
end
-- Hide a screen. The screen must either be at the top of the stack or
-- visible but not added to the stack (through the no_stack option)
-- @param id (string|hash) - Id of the screen to show

View File

@ -133,6 +133,22 @@ return function()
assert_stack({ })
end)
it("should be able to replace screens at the top of the stack", function()
monarch.show(SCREEN1_STR)
assert(wait_until_shown(SCREEN1), "Screen1 was never shown")
assert_stack({ SCREEN1 })
monarch.show(SCREEN2)
assert(wait_until_hidden(SCREEN1), "Screen1 was never hidden")
assert(wait_until_shown(SCREEN2), "Screen2 was never shown")
assert_stack({ SCREEN1, SCREEN2 })
monarch.replace(SCREEN1)
assert(wait_until_hidden(SCREEN2), "Screen2 was never hidden")
assert(wait_until_shown(SCREEN1), "Screen1 was never shown")
assert_stack({ SCREEN1, SCREEN1 })
end)
it("should be able to tell if a screen is visible or not", function()
assert(not monarch.is_visible(SCREEN1))
monarch.show(SCREEN1)
@ -302,6 +318,20 @@ return function()
assert_stack({ SCREEN1, SCREEN2 })
end)
it("should close any open popups when replacing a non-popup", function()
monarch.show(SCREEN1)
assert(wait_until_shown(SCREEN1), "Screen1 was never shown")
assert_stack({ SCREEN1 })
monarch.show(POPUP1)
assert(wait_until_shown(POPUP1), "Popup1 was never shown")
assert_stack({ SCREEN1, POPUP1 })
monarch.show(POPUP2)
assert(wait_until_shown(POPUP2), "Popup2 was never shown")
assert_stack({ SCREEN1, POPUP1, POPUP2 })
monarch.replace(SCREEN2)
assert(wait_until_shown(SCREEN2), "Popup2 was never shown")
assert_stack({ SCREEN2 })
end)
it("should be able to get the id of the screen at the top and bottom of the stack", function()
assert(monarch.top() == nil)