3
0
mirror of https://github.com/britzl/monarch.git synced 2025-11-26 19:00:53 +01:00

Compare commits

..

4 Commits
3.4.5 ... 3.6.1

Author SHA1 Message Date
Björn Ritzl
286a270a1c Check if screen was loaded before trying to unload 2022-07-05 22:54:40 +02:00
Björn Ritzl
c0d45c3d5c Added keep_loaded option to preload()
Fixes #88
2022-07-04 22:43:25 +02:00
Björn Ritzl
bcc6264cd4 Remove screen from stack when unregistered
Fixes #87
2022-05-29 14:47:34 +02:00
Björn Ritzl
1dec704047 Delay reset of timestep when going back from popup
Fixes #84
2022-02-23 12:46:04 +01:00
3 changed files with 58 additions and 9 deletions

View File

@@ -48,13 +48,18 @@ Go back to a previous Monarch screen. This operation will be added to the queue
* `callback` (function) - Optional function to call when the previous screen is visible.
## monarch.preload(screen_id, [callback])
## monarch.preload(screen_id, [options], [callback])
Preload a Monarch screen. This will load but not enable the screen. This is useful for content heavy screens that you wish to be able to show without having to wait for it load. This operation will be added to the queue if Monarch is busy.
**PARAMETERS**
* `screen_id` (string|hash) - Id of the screen to preload.
* `options` (table)
* `callback` (function) - Optional function to call when the screen is preloaded.
The options table can contain the following fields:
* `keep_loaded` (boolean) - If the `keep_loaded` flag is set Monarch will keep the screen preloaded even after a `hide()` or `back()` navigation event that normally would unload the screen.
## monarch.is_preloading(screen_id)
Check if a Monarch screen is preloading (via monarch.preload() or the Preload screen setting).

View File

@@ -298,6 +298,12 @@ function M.unregister(id)
log("unregister()", id)
local screen = screens[id]
screens[id] = nil
-- remove screen from stack
for i = #stack, 1, -1 do
if stack[i].id == id then
table.remove(stack, i)
end
end
end
local function acquire_input(screen)
@@ -348,8 +354,10 @@ local function unload(screen, force)
if screen.proxy then
log("unload() proxy", screen.id)
if screen.auto_preload and not force then
msg.post(screen.proxy, DISABLE)
screen.loaded = false
if screen.loaded then
msg.post(screen.proxy, DISABLE)
screen.loaded = false
end
screen.preloaded = true
else
screen.wait_for = PROXY_UNLOADED
@@ -650,10 +658,10 @@ local function back_out(screen, next_screen, wait_for_transition, cb)
change_context(screen)
release_input(screen, next_screen)
focus_lost(screen, next_screen)
transition(screen, M.TRANSITION.BACK_OUT, { next_screen = next_screen and next_screen.id }, wait_for_transition)
if next_screen and screen.popup then
reset_timestep(next_screen)
end
transition(screen, M.TRANSITION.BACK_OUT, { next_screen = next_screen and next_screen.id }, wait_for_transition)
screen.visible = false
unload(screen)
active_transition_count = active_transition_count - 1
@@ -921,9 +929,20 @@ function M.back(data, cb)
if data then
top.data = data
end
back_in(top, screen, DO_NOT_WAIT_FOR_TRANSITION, function()
back_out(screen, top, WAIT_FOR_TRANSITION, back_cb)
end)
-- if the screen we are backing out from is a popup and the screen we go
-- back to is not a popup we need to let the popup completely hide before
-- we start working on the screen we go back to
-- we do this to ensure that we do not reset the times step of the screen
-- we go back to until it is no longer obscured by the popup
if screen.popup and not top.popup then
back_out(screen, top, WAIT_FOR_TRANSITION, function()
back_in(top, screen, WAIT_FOR_TRANSITION, back_cb)
end)
else
back_in(top, screen, DO_NOT_WAIT_FOR_TRANSITION, function()
back_out(screen, top, WAIT_FOR_TRANSITION, back_cb)
end)
end
else
back_out(screen, top, WAIT_FOR_TRANSITION, back_cb)
end
@@ -979,12 +998,19 @@ end
--- Preload a screen. This will load but not enable and show a screen. Useful for "heavier" screens
-- that you wish to show without any delay.
-- @param id (string|hash) - Id of the screen to preload
-- @param options (table)
-- @param cb (function) - Optional callback to invoke when screen is loaded
function M.preload(id, cb)
function M.preload(id, options, cb)
assert(id, "You must provide a screen id")
id = tohash(id)
assert(screens[id], ("There is no screen registered with id %s"):format(tostring(id)))
-- support old function signature (id, cb)
if type(options) == "function" and not cb then
cb = options
options = nil
end
log("preload() queuing action", id)
queue_action(function(action_done, action_error)
log("preload()", id)
@@ -995,6 +1021,10 @@ function M.preload(id, cb)
return
end
-- keep_loaded is an option for monarch.preload()
-- use it to get the same behavior as the auto preload checkbox
screen.auto_preload = screen.auto_preload or options and options.keep_loaded
if screen.preloaded or screen.loaded then
pcallfn(cb)
pcallfn(action_done)

View File

@@ -377,7 +377,21 @@ return function()
end)
assert(not monarch.is_preloading(TRANSITION1))
end)
it("should be able to preload a screen and keep it loaded", function()
assert(not monarch.is_preloading(TRANSITION1))
monarch.preload(TRANSITION1, { keep_loaded = true })
wait_until_done(function(done)
monarch.when_preloaded(TRANSITION1, done)
end)
monarch.show(TRANSITION1)
assert(wait_until_visible(TRANSITION1), "Transition1 was never shown")
monarch.back()
assert(wait_until_hidden(TRANSITION1), "Transition1 was never hidden")
assert(monarch.is_preloaded(TRANSITION1))
end)
it("should ignore any preload calls while busy", function()
monarch.show(TRANSITION1)
-- previously a call to preload() while also showing a screen would