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

Changed from controller_url to focus_url. Improved docs

This commit is contained in:
Björn Ritzl 2017-09-28 08:22:05 +02:00
parent e24acb51d8
commit e46a703b25
5 changed files with 79 additions and 33 deletions

View File

@ -15,11 +15,8 @@ Monarch screens are created in individual collections and loaded through collect
* **Screen Proxy (url)** - The URL to the collection proxy component containing the actual screen. Defaults to ````#collectionproxy```` * **Screen Proxy (url)** - The URL to the collection proxy component containing the actual screen. Defaults to ````#collectionproxy````
* **Screen Id (hash)** - A unique id that can be used to reference the screen when navigating your app * **Screen Id (hash)** - A unique id that can be used to reference the screen when navigating your app
* **Popup (boolean)** - Check this if the screen should be treated as a [popup](#popups) * **Popup (boolean)** - Check this if the screen should be treated as a [popup](#popups)
* **Transition Show In (url)** - Optional URL to call when the screen is about to be shown. Use this to trigger a transition (see the section on [transitions](#transitions)) * **Transition Url (url)** - Optional URL to call when the screen is about to be shown/hidden. Use this to trigger a transition (see the section on [transitions](#transitions))
* **Transition Show Out (url)** - Optional URL to call when the screen is about to be hidden. Use this to trigger a transition (see the section on [transitions](#transitions)) * **Controller Url (url)** - Optional URL to call when the screen gains or loses focus.
* **Transition Back In (url)** - Optional URL to call when the screen is about to be shown when navigating back in the screen hierarchy. Use this to trigger a transition (see the section on [transitions](#transitions))
* **Transition Back Out (url)** - Optional URL to call when the screen is about to be hidden when navigating back in the screen hierarchy. Use this to trigger a transition (see the section on [transitions](#transitions))
## Navigating between screens ## Navigating between screens
The navigation in Monarch is based around a stack of screens. When a screen is shown it is pushed to the top of the stack. When going back to a previous screen the topmost screen on the stack is removed. Example: The navigation in Monarch is based around a stack of screens. When a screen is shown it is pushed to the top of the stack. When going back to a previous screen the topmost screen on the stack is removed. Example:
@ -35,7 +32,7 @@ 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: You show a screen in one of two ways:
1. Post a ````show```` message to the ````screen.script```` 1. Post a ````show```` message to the ````screen.script````
2. Call ````monarch.show(screen_id, [options], [callback])```` 2. Call ````monarch.show(screen_id, [options], [data], [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). 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).
@ -54,7 +51,7 @@ You navigate back in the screen hierarchy in one of two ways:
## Input focus ## Input focus
Monarch will acquire and release input focus on the screens and ensure that only the top-most screen will ever have input focus. Monarch will acquire and release input focus on the game objects containing the proxies to the screens and ensure that only the top-most screen will ever have input focus.
## Popups ## Popups
A screen that is flagged as a popup (see list of screen properties above) will be treated slightly differently when it comes to navigation. If a popup is at the top of the stack (ie currently shown) and another screen or popup is shown then the current popup will be removed from the stack. This means that it is not possible to have a popup anywhere in the stack but the top. This also means that you cannot navigate back to a popup since popups can only exist on the top of the stack. Another important difference between normal screens and popups is that when a popup is shown on top of a non-popup the current top screen will not be unloaded and instead remain visible in the background. A screen that is flagged as a popup (see list of screen properties above) will be treated slightly differently when it comes to navigation. If a popup is at the top of the stack (ie currently shown) and another screen or popup is shown then the current popup will be removed from the stack. This means that it is not possible to have a popup anywhere in the stack but the top. This also means that you cannot navigate back to a popup since popups can only exist on the top of the stack. Another important difference between normal screens and popups is that when a popup is shown on top of a non-popup the current top screen will not be unloaded and instead remain visible in the background.
@ -92,5 +89,49 @@ When a transition is completed it is up to the developer to send a ````transitio
self.transition.handle(message_id, message, sender) self.transition.handle(message_id, message, sender)
end end
## Screen focus gain/loss
Monarch will send focus gain and focus loss messages if a controller url was provided when the screen was created. Example:
local monarch = require "monarch.monarch"
function on_message(self, message_id, message, sender)
if message_id == monarch.FOCUS_GAINED then
print("Focus gained")
elseif message_id == monarch.FOCUS_LOST then
print("Focus lost")
end
end
## Callbacks ## 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. 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.
## Monarch API
### monarch.show(screen_id, [options], [data], [callback])
Show a Monarch screen
**PARAMETERS**
* ```screen_id``` (hash) - Id of the screen to show.
* ```options``` (table) - Options when showing the new screen (see below).
* ```data``` (table) - Optional data to associate with the screen. Retrieve using ```monarch.data()```.
* ```callback``` (function) - Function to call when the new screen is visible.
The options table can contain the following fields:
* ```clear``` (boolean) - If the clear flag is set Monarch will search the stack for the screen that is to be shown. 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.
### monarch.back([data], [callback])
Go back to a previous Monarch screen
**PARAMETERS**
* ```data``` (table) - Optional data to associate with the screen you are going back to. Retrieve using ```monarch.data()```.
* ```callback``` (function) - Function to call when the previous screen is visible.
### monarch.data(screen_id)
Get the data associated with a screen (from a call to ```monarch.show()``` or ```monarch.back()```).
**PARAMETERS**
* ```screen_id``` (hash) - Id of the screen to get data for
**RETURN**
* ```data``` (table) - Data associated with the screen.

View File

@ -81,7 +81,7 @@ embedded_instances {
" }\n" " }\n"
"}\n" "}\n"
"components {\n" "components {\n"
" id: \"main1\"\n" " id: \"gui\"\n"
" component: \"/example/debug.gui\"\n" " component: \"/example/debug.gui\"\n"
" position {\n" " position {\n"
" x: 0.0\n" " x: 0.0\n"

View File

@ -4,14 +4,17 @@ local screens = {}
local stack = {} local stack = {}
local CONTEXT = hash("monarch_context")
local PROXY_LOADED = hash("proxy_loaded")
local PROXY_UNLOADED = hash("proxy_unloaded")
M.TRANSITION_DONE = hash("transition_done") M.TRANSITION_DONE = hash("transition_done")
M.CONTEXT = hash("monarch_context")
M.FOCUS_GAINED = hash("monarch_focus_gained") M.FOCUS_GAINED = hash("monarch_focus_gained")
M.FOCUS_LOST = hash("monarch_focus_lost")
local function screen_from_proxy(proxy) local function screen_from_proxy(proxy)
for id,screen in pairs(screens) do for _,screen in pairs(screens) do
if screen.proxy == proxy then if screen.proxy == proxy then
return screen return screen
end end
@ -20,7 +23,7 @@ end
local function screen_from_script() local function screen_from_script()
local url = msg.url() local url = msg.url()
for id,screen in pairs(screens) do for _,screen in pairs(screens) do
if screen.script == url then if screen.script == url then
return screen return screen
end end
@ -36,7 +39,7 @@ local function in_stack(id)
return false return false
end end
function M.register(id, proxy, popup, transition_url, controller_url) function M.register(id, proxy, popup, transition_url, focus_url)
assert(not screens[id], ("There is already a screen registered with id %s"):format(tostring(id))) assert(not screens[id], ("There is already a screen registered with id %s"):format(tostring(id)))
screens[id] = { screens[id] = {
id = id, id = id,
@ -44,7 +47,7 @@ function M.register(id, proxy, popup, transition_url, controller_url)
script = msg.url(), script = msg.url(),
popup = popup, popup = popup,
transition_url = transition_url, transition_url = transition_url,
controller_url = controller_url, focus_url = focus_url,
} }
end end
@ -58,7 +61,7 @@ local function show_out(screen, next_screen, cb)
co = coroutine.create(function() co = coroutine.create(function()
screen.co = co screen.co = co
msg.post(screen.script, "release_input_focus") msg.post(screen.script, "release_input_focus")
msg.post(screen.script, M.CONTEXT) msg.post(screen.script, CONTEXT)
coroutine.yield() coroutine.yield()
if not next_screen.popup then if not next_screen.popup then
msg.post(screen.transition_url, "transition_show_out") msg.post(screen.transition_url, "transition_show_out")
@ -66,6 +69,9 @@ local function show_out(screen, next_screen, cb)
msg.post(screen.proxy, "unload") msg.post(screen.proxy, "unload")
coroutine.yield() coroutine.yield()
end end
if screen.focus_url then
msg.post(screen.focus_url, M.FOCUS_LOST)
end
screen.co = nil screen.co = nil
if cb then cb() end if cb then cb() end
end) end)
@ -76,7 +82,7 @@ local function show_in(screen, cb)
local co local co
co = coroutine.create(function() co = coroutine.create(function()
screen.co = co screen.co = co
msg.post(screen.script, M.CONTEXT) msg.post(screen.script, CONTEXT)
coroutine.yield() coroutine.yield()
msg.post(screen.proxy, "async_load") msg.post(screen.proxy, "async_load")
coroutine.yield() coroutine.yield()
@ -85,8 +91,8 @@ local function show_in(screen, cb)
msg.post(screen.transition_url, "transition_show_in") msg.post(screen.transition_url, "transition_show_in")
coroutine.yield() coroutine.yield()
msg.post(screen.script, "acquire_input_focus") msg.post(screen.script, "acquire_input_focus")
if screen.controller_url then if screen.focus_url then
msg.post(screen.controller_url, M.FOCUS_GAINED) msg.post(screen.focus_url, M.FOCUS_GAINED)
end end
screen.co = nil screen.co = nil
if cb then cb() end if cb then cb() end
@ -98,7 +104,7 @@ local function back_in(screen, previous_screen, cb)
local co local co
co = coroutine.create(function() co = coroutine.create(function()
screen.co = co screen.co = co
msg.post(screen.script, M.CONTEXT) msg.post(screen.script, CONTEXT)
coroutine.yield() coroutine.yield()
if not previous_screen.popup then if not previous_screen.popup then
msg.post(screen.proxy, "async_load") msg.post(screen.proxy, "async_load")
@ -108,8 +114,8 @@ local function back_in(screen, previous_screen, cb)
coroutine.yield() coroutine.yield()
end end
msg.post(screen.script, "acquire_input_focus") msg.post(screen.script, "acquire_input_focus")
if screen.controller_url then if screen.focus_url then
msg.post(screen.controller_url, M.FOCUS_GAINED) msg.post(screen.focus_url, M.FOCUS_GAINED)
end end
screen.co = nil screen.co = nil
if cb then cb() end if cb then cb() end
@ -122,11 +128,14 @@ local function back_out(screen, cb)
co = coroutine.create(function() co = coroutine.create(function()
screen.co = co screen.co = co
msg.post(screen.script, "release_input_focus") msg.post(screen.script, "release_input_focus")
msg.post(screen.script, M.CONTEXT) msg.post(screen.script, CONTEXT)
coroutine.yield() coroutine.yield()
msg.post(screen.transition_url, "transition_back_out") msg.post(screen.transition_url, "transition_back_out")
coroutine.yield() coroutine.yield()
msg.post(screen.proxy, "unload") msg.post(screen.proxy, "unload")
if screen.focus_url then
msg.post(screen.focus_url, M.FOCUS_LOST)
end
screen.co = nil screen.co = nil
if cb then cb() end if cb then cb() end
end) end)
@ -212,14 +221,14 @@ end
function M.on_message(message_id, message, sender) function M.on_message(message_id, message, sender)
if message_id == hash("proxy_loaded") then if message_id == PROXY_LOADED then
local screen = screen_from_proxy(sender) local screen = screen_from_proxy(sender)
assert(screen, "Unable to find screen for loaded proxy") assert(screen, "Unable to find screen for loaded proxy")
coroutine.resume(screen.co) coroutine.resume(screen.co)
elseif message_id == hash("proxy_unloaded") then elseif message_id == PROXY_UNLOADED then
local screen = screen_from_proxy(sender) local screen = screen_from_proxy(sender)
assert(screen, "Unable to find screen for unloaded proxy") assert(screen, "Unable to find screen for unloaded proxy")
elseif message_id == M.CONTEXT then elseif message_id == CONTEXT then
local screen = screen_from_script() local screen = screen_from_script()
assert(screen, "Unable to find screen for current script url") assert(screen, "Unable to find screen for current script url")
coroutine.resume(screen.co) coroutine.resume(screen.co)

View File

@ -4,11 +4,11 @@ go.property("screen_proxy", msg.url("#collectionproxy"))
go.property("screen_id", hash("")) go.property("screen_id", hash(""))
go.property("popup", false) go.property("popup", false)
go.property("transition_url", msg.url()) go.property("transition_url", msg.url())
go.property("controller_url", msg.url()) go.property("focus_url", msg.url())
function init(self) function init(self)
monarch.register(self.screen_id, self.screen_proxy, self.popup, self.transition_url, self.controller_url) monarch.register(self.screen_id, self.screen_proxy, self.popup, self.transition_url, self.focus_url)
end end
function final(self) function final(self)

View File

@ -92,7 +92,6 @@ function M.create(node)
-- @param delay Transition delay -- @param delay Transition delay
function instance.show_in(fn, easing, duration, delay) function instance.show_in(fn, easing, duration, delay)
transitions[hash("transition_show_in")] = function(url) transitions[hash("transition_show_in")] = function(url)
print("transition_show_in", url, fn)
fn(node, initial_position, easing, duration, delay or 0, url) fn(node, initial_position, easing, duration, delay or 0, url)
end end
return instance return instance
@ -102,7 +101,6 @@ function M.create(node)
-- from when showing another screen -- from when showing another screen
function instance.show_out(fn, easing, duration, delay) function instance.show_out(fn, easing, duration, delay)
transitions[hash("transition_show_out")] = function(url) transitions[hash("transition_show_out")] = function(url)
print("transition_show_out")
fn(node, initial_position, easing, duration, delay or 0, url) fn(node, initial_position, easing, duration, delay or 0, url)
end end
return instance return instance
@ -112,7 +110,6 @@ function M.create(node)
-- to when navigating back in the screen stack -- to when navigating back in the screen stack
function instance.back_in(fn, easing, duration, delay) function instance.back_in(fn, easing, duration, delay)
transitions[hash("transition_back_in")] = function(url) transitions[hash("transition_back_in")] = function(url)
print("transition_back_in")
fn(node, initial_position, easing, duration, delay or 0, url) fn(node, initial_position, easing, duration, delay or 0, url)
end end
return instance return instance
@ -122,7 +119,6 @@ function M.create(node)
-- from when navigating back in the screen stack -- from when navigating back in the screen stack
function instance.back_out(fn, easing, duration, delay) function instance.back_out(fn, easing, duration, delay)
transitions[hash("transition_back_out")] = function(url) transitions[hash("transition_back_out")] = function(url)
print("transition_back_out")
fn(node, initial_position, easing, duration, delay or 0, url) fn(node, initial_position, easing, duration, delay or 0, url)
end end
return instance return instance