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

Compare commits

..

47 Commits

Author SHA1 Message Date
Björn Ritzl
9a6d5f7a7b Update ci-workflow.yml 2025-05-15 08:58:40 +02:00
Björn Ritzl
d68e27b2ad Update ci-workflow.yml 2025-05-15 08:57:50 +02:00
Björn Ritzl
5525707744 Cleaned up callback tests
Fixes #
2025-05-14 22:56:47 +02:00
Alexander
aea267cc35
fix gui template (#112)
https://github.com/britzl/monarch/issues/111
2024-09-27 08:58:51 +02:00
Pawel
6ba3064749
Fixed an error that appears when trying to delete an instance that is already deleted. (#109)
* Prevent deleting already removed instances.

* Prehashed empty hash.

* Use go.exists instead of pcall, when detecting non existing instances.
2024-03-04 16:06:56 +01:00
Björn Ritzl
b78b896ada Update README_API.md 2024-01-30 11:08:38 +01:00
SalavatR
679482f84d
Add a check for missing resources in collection proxies. (#107)
* Update monarch.lua

* Update monarch.lua

* Update monarch.lua
2024-01-30 11:03:37 +01:00
Björn Ritzl
4c6e26fd71 Removed backward comp fix for monarch.back() 2024-01-12 08:31:48 +01:00
bedryck
00c30792a9
fix a problem of sequential in back function (#104) 2024-01-12 08:22:43 +01:00
Björn Ritzl
b01f5d28c3 Update monarch.lua 2023-12-27 15:54:09 +01:00
Pete Garcin
43e847dacc
Guard DEPRECATED transition_id overwriting transition_url (#100) 2023-12-27 15:52:36 +01:00
Björn Ritzl
ce5ca26b6c Update README_TRANSITIONS.md
Fixes #102
2023-12-27 15:51:38 +01:00
Björn Ritzl
742779d749 Allow monarch.post() to loaded screens
Fixes #98
2023-10-26 13:54:14 +02:00
Björn Ritzl
84944f3f22 Added monarch.is_loaded() 2023-10-26 11:43:19 +02:00
Björn Ritzl
c473aa053c Update monarch.lua 2023-08-31 09:25:00 +02:00
Björn Ritzl
169236acbd Improved on_post() to also accept a url 2023-08-31 09:22:24 +02:00
Björn Ritzl
b7053d2ce4 Fixed another back issue (and tests) 2023-08-10 00:21:15 +02:00
Björn Ritzl
91204ca30b
Wait for both in and out transitions (#97) 2023-08-10 00:08:10 +02:00
Björn Ritzl
6f79bd0326 Swap transition count and listener order 2023-08-08 23:51:48 +02:00
Björn Ritzl
e5214edb22 Fix back() callback 2023-08-08 23:51:29 +02:00
Björn Ritzl
1d4e48c0de Update test_monarch.lua 2023-08-08 22:55:29 +02:00
Björn Ritzl
5bdc3e4540 Added option table to back() 2023-08-08 22:53:00 +02:00
Björn Ritzl
85123c84e9 Show how to use monarch listeners 2023-08-08 22:49:58 +02:00
Björn Ritzl
a605f4f6f8 Fixed tests 2023-08-03 10:42:06 +02:00
Björn Ritzl
5d8fa8e220 monarch.post() requires monarch.on_post() 2023-08-03 08:35:04 +02:00
Björn Ritzl
df2a2a62ea Improved screen proxy url detection 2023-08-03 08:34:26 +02:00
Björn Ritzl
4e13660d63 Use new on_transition() 2023-08-02 07:47:47 +02:00
Björn Ritzl
0191a4e540 Set focus, transition and receiver as deprecated 2023-08-02 07:47:32 +02:00
Björn Ritzl
c601174b9d
Improved handling of unregistered screens (#93)
* Set cowait flag

* Set screen as unregistered

* Do not process screen which have been unregistered

* Java 17
2023-07-29 11:28:18 +02:00
Björn Ritzl
66d2c98ccc Clear wait_for flag on proxy loaded 2023-07-29 10:29:51 +02:00
Björn Ritzl
e8249229b9 Differentiate messages and wait for constants 2023-07-29 10:29:21 +02:00
Björn Ritzl
2eb67bf29d Squashed commit of the following:
commit 698cdba5a469f900b902da360ad05e103cd1a39b
Author: Björn Ritzl <bjorn.ritzl@gmail.com>
Date:   Wed Mar 29 11:10:49 2023 +0200

    Documentation

commit d8de338a465066a9b9ff1bb6d20b5476e78d6359
Author: Björn Ritzl <bjorn.ritzl@gmail.com>
Date:   Wed Mar 29 10:40:38 2023 +0200

    Added focus and post listener setup functions

commit 55910abd74542513795dae3ccb9b4fd87da22b74
Author: Björn Ritzl <bjorn.ritzl@gmail.com>
Date:   Wed Mar 29 09:49:00 2023 +0200

    Update gui.lua

commit a055af032fb47d67647e0b7bc09ad4721fd623d7
Author: Björn Ritzl <bjorn.ritzl@gmail.com>
Date:   Wed Mar 29 09:19:49 2023 +0200

    Improve transition setup
2023-07-27 23:53:37 +02:00
Björn Ritzl
fe8341263a Update gui.lua 2023-03-29 09:20:37 +02:00
Björn Ritzl
e0b0a286e3 Added sliding window example 2023-03-28 15:42:39 +02:00
Björn Ritzl
c14e4a8a46 Added more screens to the basic example 2023-02-10 00:09:06 +01:00
Björn Ritzl
482e319285 Removed luacheckrc file 2023-02-09 23:39:44 +01:00
Björn Ritzl
9c7ce61f6f Removed unused local var 2023-02-09 23:39:04 +01:00
Björn Ritzl
f5afbad233 Fixed global assignment 2023-02-09 23:38:53 +01:00
Björn Ritzl
6fdde9d2a8 Update run.sh 2023-01-22 15:45:39 +01:00
Björn Ritzl
d963b583b1 Moved test script 2023-01-22 15:39:02 +01:00
Björn Ritzl
6fe59c92c4 Make sure to force unload a preloaded screen 2022-07-23 00:09:51 +02:00
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
Björn Ritzl
9764c68475 Update callback_tracker.lua
Fixes #83
2022-01-27 12:16:43 +01:00
Björn Ritzl
d57d550859 Fixed issues with missing variables 2022-01-27 12:15:52 +01:00
51 changed files with 2911 additions and 384 deletions

View File

@ -7,13 +7,13 @@ jobs:
name: Build and run
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-java@v1
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9
with:
java-version: '11'
java-version: '21.0.5+11.0.LTS'
distribution: 'temurin'
- name: Run.sh
env:
DEFOLD_USER: bjorn.ritzl@gmail.com
DEFOLD_AUTH: foobar
DEFOLD_BOOSTRAP_COLLECTION: /test/test.collectionc
run: ./.travis/run.sh
run: ./.test/run.sh

3
.gitignore vendored
View File

@ -9,3 +9,6 @@ build
builtins
.internal
luacov.report.out
/.editor_settings
manifest.private.der
manifest.public.der

View File

@ -1,42 +0,0 @@
std = "max"
files['.luacheckrc'].global = false
unused_args = false
globals = {
"sys",
"go",
"gui",
"label",
"render",
"crash",
"sprite",
"sound",
"tilemap",
"spine",
"particlefx",
"physics",
"factory",
"collectionfactory",
"iac",
"msg",
"vmath",
"url",
"http",
"image",
"json",
"zlib",
"iap",
"push",
"facebook",
"hash",
"hash_to_hex",
"pprint",
"init",
"final",
"update",
"on_input",
"on_message",
"on_reload",
"window",
"unityads"
}

View File

@ -5,7 +5,6 @@ else
PLATFORM="$1"
fi
echo "${PLATFORM}"
# {"version": "1.2.89", "sha1": "5ca3dd134cc960c35ecefe12f6dc81a48f212d40"}
@ -16,26 +15,28 @@ echo "Using Defold dmengine_headless version ${SHA1}"
# Create dmengine_headless and bob.jar URLs
DMENGINE_URL="http://d.defold.com/archive/${SHA1}/engine/${PLATFORM}/dmengine_headless"
BOB_URL="http://d.defold.com/archive/${SHA1}/bob/bob.jar"
DMENGINE_FILE=dmengine_headless_${SHA1}
BOB_FILE=bob_${SHA1}.jar
# Download dmengine_headless
echo "Downloading ${DMENGINE_URL}"
curl -o dmengine_headless ${DMENGINE_URL}
chmod +x dmengine_headless
if ! [ -f ${DMENGINE_FILE} ]; then
echo "Downloading ${DMENGINE_URL} to ${DMENGINE_FILE}"
curl -L -o ${DMENGINE_FILE} ${DMENGINE_URL}
chmod +x ${DMENGINE_FILE}
fi
# Download bob.jar
echo "Downloading ${BOB_URL}"
curl -o bob.jar ${BOB_URL}
if ! [ -f ${BOB_FILE} ]; then
echo "Downloading ${BOB_URL} to ${BOB_FILE}"
curl -L -o ${BOB_FILE} ${BOB_URL}
fi
# Fetch libraries
echo "Running bob.jar - resolving dependencies"
java -jar bob.jar --auth "foobar" --email "john@doe.com" resolve
echo "Running ${BOB_FILE} - resolving dependencies"
java -jar ${BOB_FILE} --auth "foobar" --email "john@doe.com" resolve
echo "Running bob.jar - building"
java -jar bob.jar --debug build --keep-unused
echo "Running ${BOB_FILE} - building"
java -jar ${BOB_FILE} --debug build --settings=test.settings
echo "Starting dmengine_headless"
if [ -n "${DEFOLD_BOOSTRAP_COLLECTION}" ]; then
./dmengine_headless --config=bootstrap.main_collection=${DEFOLD_BOOSTRAP_COLLECTION}
else
./dmengine_headless
fi
echo "Starting ${DMENGINE_FILE}"
./${DMENGINE_FILE}

View File

@ -1,30 +0,0 @@
sudo: required
dist: bionic
script:
- sudo unlink /usr/bin/gcc && sudo ln -s /usr/bin/gcc-5 /usr/bin/gcc
- gcc --version
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-5
- g++-5
language: java
jdk:
- oraclejdk11
env:
global:
- DEFOLD_BOOSTRAP_COLLECTION=/test/test.collectionc
script:
- "./.travis/run.sh"
after_success:
- bash <(curl -s https://codecov.io/bash)

View File

@ -37,9 +37,9 @@ For proxies the recommended setup is to create one game object per screen and pe
* **Timestep below Popup (number)** - Timestep to set on screen proxy when it is below a popup. This is useful when pausing animations and gameplay while a popup is open.
* **Screen Keeps Input Focus When Below Popup (boolean)** - Check this if the screen should keep input focus when it is below a popup.
* **Others Keep Input Focus When Below Screen (boolean)** - Check this if other screens should keep input focus when below this screen.
* **Transition Url (url)** - Optional URL to post messages to when the screen is about to be shown/hidden. Use this to trigger a transition (see the section on [transitions](#transitions)).
* **Focus Url (url)** - Optional URL to post messages to when the screen gains or loses focus (see the section on [screen focus](#screen-focus-gainloss)).
* **Receiver Url (url)** - Optional URL to post messages to using `monarch.post()`.
* **Transition Url (url)** - **DEPRECATED** Optional URL to post messages to when the screen is about to be shown/hidden. Use this to trigger a transition (see the section on [transitions](#transitions)).
* **Focus Url (url)** - **DEPRECATED** Optional URL to post messages to when the screen gains or loses focus (see the section on [screen focus](#screen-focus-gainloss)).
* **Receiver Url (url)** - **DEPRECATED** Optional URL to post messages to using `monarch.post()`.
* **Preload (boolean)** - Check this if the screen should be preloaded and kept loaded at all times. For a collection proxy it means that it will be async loaded but not enabled at all times while not visible. This can also temporarily be achieved through the `monarch.preload()` function.
![](docs/setup_proxy.png)
@ -53,8 +53,8 @@ For factories the recommended setup is to create one game object per screen and
* **Popup on Popup (boolean)** - Check this if the screen is a [popup](#popups) and it can be shown on top of other popups.
* **Screen Keeps Input Focus When Below Popup (boolean)** - Check this if the screen should keep input focus when it is below a popup.
* **Others Keep Input Focus When Below Screen (boolean)** - Check this if other screens should keep input focus when below this screen.
* **Transition Id (hash)** - Optional id of the game object to send a message to when the screen is about to be shown/hidden. Use this to trigger a transition (see the section on [transitions](#transitions)).
* **Focus Id (hash)** - Optional id of the game object to send a message to when the screen gains or loses focus (see the section on [screen focus](#screen-focus-gainloss)).
* **Transition Id (hash)** - **DEPRECATED** Optional id of the game object to send a message to when the screen is about to be shown/hidden. Use this to trigger a transition (see the section on [transitions](#transitions)).
* **Focus Id (hash)** - **DEPRECATED** Optional id of the game object to send a message to when the screen gains or loses focus (see the section on [screen focus](#screen-focus-gainloss)).
* **Preload (boolean)** - Check this if the screen should be preloaded and kept loaded at all times. For a collection factory this means that its resources will be dynamically loaded at all times. This can also temporarily be achieved through the `monarch.preload()` function.
![](docs/setup_factory.png)
@ -161,18 +161,30 @@ You can add optional transitions when navigating between screens. This is [descr
## Screen focus gain/loss
Monarch will send focus gain and focus loss messages if a `Focus Url` (proxy) or `Focus Id` (collectionfactory) was provided when the screen was created. The focus gained message will contain the id of the previous screen and the focus loss message will contain the id of the next screen. Example:
Monarch will send focus gain and focus loss messages if a focus change listener has been set using `monarch.on_focus_change(screen_id, fn)`
DEPRECATED: ~~Monarch will send focus gain and focus loss messages if a `Focus Url` (proxy) or `Focus Id` (collectionfactory) was provided when the screen was created.~~
The focus gained message will contain the id of the previous screen and the focus loss message will contain the id of the next screen. Example:
```lua
local monarch = require "monarch.monarch"
function on_message(self, message_id, message, sender)
if message_id == monarch.FOCUS.GAINED then
print("Focus gained, previous screen: ", message.id)
elseif message_id == monarch.FOCUS.LOST then
print("Focus lost, next screen: ", message.id)
end
function init(self)
monarch.on_focus_changed("foobar", function(message_id, message, sender)
if message_id == monarch.FOCUS.GAINED then
print("Focus gained, previous screen: ", message.id)
elseif message_id == monarch.FOCUS.LOST then
print("Focus lost, next screen: ", message.id)
end
end)
end
function on_message(self, message_id, message, sender)
monarch.on_message(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_show_in` (or the `transition_back_in` in the case of a `monarch.back()` call) transition is completed. The transition is considered completed when a `transition_done` message has been received (see section on [transitions](#transitions) above).
@ -180,10 +192,3 @@ Both the `monarch.show()` and `monarch.back()` functions take an optional callba
## Monarch API
The full [Monarch API is documented here](/README_API.md).
## Monarch FAQ
**Q**: Why am I getting `ERROR GAMEOBJECT: The collection 'default' could not be created since there is already a socket with the same name`?
**A**: Each collection that you use must be given a unique id. In this case you have more than one collection loaded with the id `default`. Select the root of each collection in the Outline panel and change the Name field in the properties panel from the default value of `default`.

View File

@ -40,21 +40,31 @@ Clear the stack of screens completely. Any visible screen will be hidden by navi
* `callback` (function) - Optional function to call when the stack has been cleared.
## monarch.back([data], [callback])
## monarch.back([options], [data], [callback])
Go back to a previous Monarch screen. This operation will be added to the queue if Monarch is busy.
**PARAMETERS**
* `options` (table) - Options when showing the new screen (see below).
* `data` (table) - Optional data to associate with the screen you are going back to. Retrieve using `monarch.data()`.
* `callback` (function) - Optional function to call when the previous screen is visible.
The options table can contain the following fields:
## monarch.preload(screen_id, [callback])
* `sequential` (boolean) - If the `sequential` flag is set Monarch will start loading the screen only after the previous screen finished transitioning out.
## 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).
@ -172,7 +182,7 @@ Remove a previously added listener.
## monarch.post(screen_id, message_id, [message])
Post a message to a visible screen. If the screen is created through a collection proxy it must have specified a receiver url. If the screen is created through a collection factory the function will post the message to all game objects within the collection.
Post a message to a visible screen. The screen must have set a message listener using `monarch.on_post()`.
**PARAMETERS**
* `screen_id` (string|hash) - Id of the screen to post message to
@ -184,6 +194,41 @@ Post a message to a visible screen. If the screen is created through a collectio
* `error` (string|nil) - Error message if unable to send message
## monarch.on_transition(screen_id, fn)
Set a function to be called when a screen should transition in our out. The function will receive (message_id, message, sender) with `message_id` being one of the transition constants.
IMPORTANT! You must call `monarch.on_message(message_id, message, sender)` from the same script as this function was called.
**PARAMETERS**
* `screen_id` (string|hash) - Id of the screen
* `fn` (function) - The function to call when a transition should start
## monarch.on_focus_change(screen_id, fn)
Set a function to be called when a screen gains or loses focus. The function will receive (message_id, message, sender) with `message_id` being one of the focus change constants.
IMPORTANT! You must call `monarch.on_message(message_id, message, sender)` from the same script as this function was called.
**PARAMETERS**
* `screen_id` (string|hash) - Id of the screen
* `fn` (function) - The function to call screen focus changes
## monarch.on_post(screen_id, fn_or_url)
Set either a function to be called when `msg.post()` is called on a specific screen or a URL where the message is sent.
IMPORTANT! If you provide a function you must also make sure to call `monarch.on_message(message_id, message, sender)` from the same script as this function was called.
**PARAMETERS**
* `screen_id` (string|hash) - Id of the screen
* `fn_or_url` (function) - The function to call or URL to send message to
## monarch.has_missing_resources(screen_id)
Check if a screen has any missing resources. If the screen is loaded by a collection proxy with Load Dynamically this will use `collectionproxy.missing_resources()`. For other cases this function will always return false.
**RETURN**
* `result` (boolean) - true if the screen has missing resources
## monarch.debug()
Enable verbose logging of the internals of Monarch.

View File

@ -1,5 +1,7 @@
# Transitions
You can add optional transitions when navigating between screens. The default behavior is that screen navigation is instant but if you have defined a transition for a screen Monarch will wait until the transition is completed before proceeding. The `Transition Url` (proxy) or `Transition Id` (collectionfactory) property described above should be the URL/Id to a script with an `on_message` handlers for the following messages:
You can add optional transitions when navigating between screens. The default behavior is that screen navigation is instant but if you have defined a transition for a screen Monarch will wait until the transition is completed before proceeding.
Transitions are configured through the `monarch.on_transition(screen_id, fn)` function. The function defines for which screen to configure transitions and sets a function to be called when a transition should be started. This function must accept (message_id, message, sender) as arguments, with `message_id` defining which type of transition to start:
* `transition_show_in` (constant defined as `monarch.TRANSITION.SHOW_IN`)
* `transition_show_out` (constant defined as `monarch.TRANSITION.SHOW_OUT`)
@ -8,6 +10,11 @@ You can add optional transitions when navigating between screens. The default be
When a transition is completed it is up to the developer to send a `transition_done` (constant `monarch.TRANSITION.DONE`) message back to the sender to indicate that the transition is completed and that Monarch can continue the navigation sequence.
## Transition URL
This property is deprecated and will be removed in a future version of Monarch.
~~It is also possible to configure transitions through the `Transition Url` (proxy) or `Transition Id` (collectionfactory) property. This property must be the URL/Id to a script with an `on_message` handlers for the transition messages mentioned above.~~
## Predefined transitions
Monarch comes with a system for setting up transitions easily in a gui_script using the `monarch.transitions.gui` module. Example:
@ -20,15 +27,17 @@ function init(self)
-- create transitions for the node 'root'
-- the node will slide in/out from left and right with
-- a specific easing, duration and delay
self.transition = transitions.create(gui.get_node("root"))
local transition = transitions.create(gui.get_node("root"))
.show_in(transitions.slide_in_right, gui.EASING_OUTQUAD, 0.6, 0)
.show_out(transitions.slide_out_left, gui.EASING_INQUAD, 0.6, 0)
.back_in(transitions.slide_in_left, gui.EASING_OUTQUAD, 0.6, 0)
.back_out(transitions.slide_out_right, gui.EASING_INQUAD, 0.6, 0)
monarch.on_transition("foobar", transition)
end
function on_message(self, message_id, message, sender)
self.transition.handle(message_id, message, sender)
monarch.on_message(message_id, message, sender)
-- you can also check when a transition has completed:
if message_id == monarch.TRANSITION.DONE and message.transition == monarch.TRANSITION.SHOW_IN then
print("Show in done!")
@ -40,7 +49,7 @@ It is also possible to assign transitions to multiple nodes:
```lua
function init(self)
self.transition = transitions.create() -- note that no node is passed to transition.create()!
local transition = transitions.create() -- note that no node is passed to transition.create()!
.show_in(gui.get_node("node1"), transitions.slide_in_right, gui.EASING_OUTQUAD, 0.6, 0)
.show_in(gui.get_node("node2"), transitions.slide_in_right, gui.EASING_OUTQUAD, 0.6, 0)
end
@ -105,13 +114,13 @@ end
function on_message(self, message_id, message, sender)
if message_id == hash("my_resize_message") then
self.transition.window_resized(message.width, message.height)
transition.window_resized(message.width, message.height)
end
end
```
## Screen stack info and transitions
The transition message sent to the Transition Url specified in the screen configuration contains additional information about the transition. For the `transition_show_in` and `transition_back_out` messages the message contains the previous screen id:
The transition message sent transition listener script contains additional information about the transition. For the `transition_show_in` and `transition_back_out` messages the message contains the previous screen id:
```lua
function on_message(self, message_id, message, sender)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 92 KiB

View File

@ -5,11 +5,13 @@ function init(self)
msg.post(".", "acquire_input_focus")
gui.set_render_order(15)
self.transition = transitions.create(gui.get_node("root"))
local transition = transitions.create(gui.get_node("root"))
.show_in(transitions.slide_in_top, gui.EASING_OUTQUAD, 0.6, 0)
.show_out(transitions.slide_out_top, gui.EASING_INQUAD, 0.6, 0)
.back_in(transitions.slide_in_top, gui.EASING_OUTQUAD, 0.6, 0)
.back_out(transitions.slide_out_top, gui.EASING_INQUAD, 0.6, 0)
monarch.on_transition("about", transition)
end
function on_input(self, action_id, action)
@ -27,5 +29,5 @@ function on_input(self, action_id, action)
end
function on_message(self, message_id, message, sender)
self.transition.handle(message_id, message, sender)
monarch.on_message(message_id, message, sender)
end

View File

@ -21,15 +21,7 @@ embedded_instances {
" value: \"menu\"\n"
" type: PROPERTY_TYPE_HASH\n"
" }\n"
" properties {\n"
" id: \"transition_id\"\n"
" value: \"/go\"\n"
" type: PROPERTY_TYPE_HASH\n"
" }\n"
" properties {\n"
" id: \"focus_id\"\n"
" value: \"/go\"\n"
" type: PROPERTY_TYPE_HASH\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
@ -37,6 +29,7 @@ embedded_instances {
" type: \"collectionfactory\"\n"
" data: \"prototype: \\\"/example/advanced/menu.collection\\\"\\n"
"load_dynamically: true\\n"
"dynamic_prototype: false\\n"
"\"\n"
" position {\n"
" x: 0.0\n"
@ -84,6 +77,8 @@ embedded_instances {
" z: 0.0\n"
" w: 1.0\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
"components {\n"
" id: \"gui\"\n"
@ -99,6 +94,8 @@ embedded_instances {
" z: 0.0\n"
" w: 1.0\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
""
position {
@ -139,10 +136,7 @@ embedded_instances {
" value: \"pregame\"\n"
" type: PROPERTY_TYPE_HASH\n"
" }\n"
" properties {\n"
" id: \"transition_url\"\n"
" value: \"pregame:/go#pregame\"\n"
" type: PROPERTY_TYPE_URL\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
@ -202,10 +196,7 @@ embedded_instances {
" value: \"game\"\n"
" type: PROPERTY_TYPE_HASH\n"
" }\n"
" properties {\n"
" id: \"transition_url\"\n"
" value: \"game:/go#game\"\n"
" type: PROPERTY_TYPE_URL\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
@ -276,20 +267,12 @@ embedded_instances {
" type: PROPERTY_TYPE_BOOLEAN\n"
" }\n"
" properties {\n"
" id: \"transition_url\"\n"
" value: \"about:/go#about\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
" properties {\n"
" id: \"focus_url\"\n"
" value: \"about:/go#about\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
" properties {\n"
" id: \"preload\"\n"
" value: \"true\"\n"
" type: PROPERTY_TYPE_BOOLEAN\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"collectionproxy\"\n"
@ -363,10 +346,7 @@ embedded_instances {
" value: \"true\"\n"
" type: PROPERTY_TYPE_BOOLEAN\n"
" }\n"
" properties {\n"
" id: \"transition_url\"\n"
" value: \"confirm:/go#confirm\"\n"
" type: PROPERTY_TYPE_URL\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
@ -426,12 +406,15 @@ embedded_instances {
" value: \"background\"\n"
" type: PROPERTY_TYPE_HASH\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"collectionfactory\"\n"
" type: \"collectionfactory\"\n"
" data: \"prototype: \\\"/example/advanced/background.collection\\\"\\n"
"load_dynamically: false\\n"
"dynamic_prototype: false\\n"
"\"\n"
" position {\n"
" x: 0.0\n"

View File

@ -7,11 +7,13 @@ function init(self)
self.no = gui.get_node("no_button")
gui.set_render_order(15)
self.transition = transitions.create(gui.get_node("root"))
local transition = transitions.create(gui.get_node("root"))
.show_in(transitions.scale_in, gui.EASING_OUTBACK, 0.3, 0)
.show_out(transitions.scale_out, gui.EASING_INBACK, 0.3, 0)
.back_in(transitions.scale_in, gui.EASING_OUTBACK, 0.3, 0)
.back_out(transitions.scale_out, gui.EASING_INBACK, 0.3, 0)
monarch.on_transition("confirm", transition)
end
function on_input(self, action_id, action)
@ -27,7 +29,7 @@ function on_input(self, action_id, action)
end
elseif gui.pick_node(self.no, action.x, action.y) then
print("no")
monarch.back(function()
monarch.back(nil, nil, function()
print("back from popup done")
end)
end
@ -35,5 +37,5 @@ function on_input(self, action_id, action)
end
function on_message(self, message_id, message, sender)
self.transition.handle(message_id, message, sender)
monarch.on_message(message_id, message, sender)
end

View File

@ -7,7 +7,8 @@ function init(self)
local data = monarch.data(hash("game"))
gui.set_text(gui.get_node("level"), tostring(data.level))
self.transition = transitions.in_right_out_left(gui.get_node("root"), 0.6, 0)
local transition = transitions.in_right_out_left(gui.get_node("root"), 0.6, 0)
monarch.on_transition("game", transition)
end
function on_input(self, action_id, action)
@ -21,5 +22,5 @@ function on_input(self, action_id, action)
end
function on_message(self, message_id, message, sender)
self.transition.handle(message_id, message, sender)
monarch.on_message(message_id, message, sender)
end

View File

@ -16,6 +16,8 @@ embedded_instances {
" z: 0.0\n"
" w: 1.0\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
""
position {
@ -76,12 +78,15 @@ embedded_instances {
" value: \"/go\"\n"
" type: PROPERTY_TYPE_HASH\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"collectionfactory\"\n"
" type: \"collectionfactory\"\n"
" data: \"prototype: \\\"/example/advanced/popup.collection\\\"\\n"
"load_dynamically: false\\n"
"dynamic_prototype: false\\n"
"\"\n"
" position {\n"
" x: 0.0\n"

View File

@ -8,7 +8,8 @@ function init(self)
gui.animate(gui.get_node("spinner"), gui.PROP_ROTATION, vmath.vector3(0, 0, -360), gui.EASING_INOUTQUAD, 2, 0, nil, gui.PLAYBACK_LOOP_FORWARD)
self.transition = transitions.fade_in_out(gui.get_node("root"), 0.6, 0)
local transition = transitions.fade_in_out(gui.get_node("root"), 0.6, 0)
monarch.on_transition("menu", transition)
end
function on_input(self, action_id, action)
@ -28,7 +29,7 @@ function on_input(self, action_id, action)
end
function on_message(self, message_id, message, sender)
self.transition.handle(message_id, message, sender)
monarch.on_message(message_id, message, sender)
if message_id == monarch.FOCUS.GAINED then
gui.set_text(gui.get_node("timestamp"), os.date())
end

View File

@ -10,11 +10,12 @@ function init(self)
gui.animate(gui.get_node("spinner"), gui.PROP_ROTATION, vmath.vector3(0, 0, -360), gui.EASING_INOUTQUAD, 2, 0, nil, gui.PLAYBACK_LOOP_FORWARD)
self.transition = transitions.create(gui.get_node("root"))
local transition = transitions.create(gui.get_node("root"))
.show_in(transitions.scale_in, gui.EASING_OUTBACK, 0.3, 0)
.show_out(transitions.scale_out, gui.EASING_INBACK, 0.3, 0)
.back_in(transitions.scale_in, gui.EASING_OUTBACK, 0.3, 0)
.back_out(transitions.scale_out, gui.EASING_INBACK, 0.3, 0)
monarch.on_transition("popup", transition)
end
function on_input(self, action_id, action)
@ -26,7 +27,7 @@ function on_input(self, action_id, action)
end)
elseif gui.pick_node(self.cancel, action.x, action.y) then
print("cancel")
monarch.back(function()
monarch.back(nil, nil, function()
print("back from popup done")
end)
elseif gui.pick_node(self.about, action.x, action.y) then
@ -39,5 +40,5 @@ function on_input(self, action_id, action)
end
function on_message(self, message_id, message, sender)
self.transition.handle(message_id, message, sender)
monarch.on_message(message_id, message, sender)
end

View File

@ -6,7 +6,8 @@ function init(self)
self.play = gui.get_node("play_button")
self.back = gui.get_node("back_button")
self.transition = transitions.in_right_out_left(gui.get_node("root"), 0.6, 0)
local transition = transitions.in_right_out_left(gui.get_node("root"), 0.6, 0)
monarch.on_transition("pregame", transition)
end
function on_input(self, action_id, action)
@ -18,7 +19,7 @@ function on_input(self, action_id, action)
end)
elseif gui.pick_node(self.back, action.x, action.y) then
print("back")
monarch.back(function()
monarch.back(nil, nil, function()
print("back from pregame done")
end)
end
@ -26,5 +27,5 @@ function on_input(self, action_id, action)
end
function on_message(self, message_id, message, sender)
self.transition.handle(message_id, message, sender)
monarch.on_message(message_id, message, sender)
end

View File

@ -21,6 +21,8 @@ embedded_instances {
" value: \"screen1\"\n"
" type: PROPERTY_TYPE_HASH\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"collectionproxy\"\n"
@ -74,6 +76,8 @@ embedded_instances {
" z: 0.0\n"
" w: 1.0\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
""
position {
@ -114,6 +118,8 @@ embedded_instances {
" value: \"screen2\"\n"
" type: PROPERTY_TYPE_HASH\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"collectionproxy\"\n"
@ -151,3 +157,133 @@ embedded_instances {
z: 1.0
}
}
embedded_instances {
id: "popup1"
data: "components {\n"
" id: \"screen_proxy\"\n"
" component: \"/monarch/screen_proxy.script\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
" properties {\n"
" id: \"screen_id\"\n"
" value: \"popup1\"\n"
" type: PROPERTY_TYPE_HASH\n"
" }\n"
" properties {\n"
" id: \"popup\"\n"
" value: \"true\"\n"
" type: PROPERTY_TYPE_BOOLEAN\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"collectionproxy\"\n"
" type: \"collectionproxy\"\n"
" data: \"collection: \\\"/example/basic/popup1.collection\\\"\\n"
"exclude: false\\n"
"\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
"}\n"
""
position {
x: 0.0
y: 0.0
z: 0.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale3 {
x: 1.0
y: 1.0
z: 1.0
}
}
embedded_instances {
id: "popup2"
data: "components {\n"
" id: \"screen_proxy\"\n"
" component: \"/monarch/screen_proxy.script\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
" properties {\n"
" id: \"screen_id\"\n"
" value: \"popup2\"\n"
" type: PROPERTY_TYPE_HASH\n"
" }\n"
" properties {\n"
" id: \"popup\"\n"
" value: \"true\"\n"
" type: PROPERTY_TYPE_BOOLEAN\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"collectionproxy\"\n"
" type: \"collectionproxy\"\n"
" data: \"collection: \\\"/example/basic/popup2.collection\\\"\\n"
"exclude: false\\n"
"\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
"}\n"
""
position {
x: 0.0
y: 0.0
z: 0.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale3 {
x: 1.0
y: 1.0
z: 1.0
}
}

View File

@ -0,0 +1,39 @@
name: "popup1"
scale_along_z: 0
embedded_instances {
id: "go"
data: "components {\n"
" id: \"popup1\"\n"
" component: \"/example/basic/popup1.gui\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
""
position {
x: 0.0
y: 0.0
z: 0.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale3 {
x: 1.0
y: 1.0
z: 1.0
}
}

385
example/basic/popup1.gui Normal file
View File

@ -0,0 +1,385 @@
script: "/example/basic/popup1.gui_script"
fonts {
name: "example"
font: "/assets/example.font"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 320.0
y: 568.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 400.0
y: 400.0
z: 0.0
w: 1.0
}
color {
x: 0.5019608
y: 0.6
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 0.0
y: 100.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "showpopup2"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_AUTO
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "SHOW POPUP 2"
font: "example"
id: "showtext"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "showpopup2"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 1.0
shadow_alpha: 1.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 0.0
y: -100.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "closepopup"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_AUTO
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "CLOSE"
font: "example"
id: "closetext"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "closepopup"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 1.0
shadow_alpha: 1.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 40.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "THIS IS POPUP 1"
font: "example"
id: "id"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "root"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 1.0
shadow_alpha: 1.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@ -0,0 +1,16 @@
local monarch = require "monarch.monarch"
function init(self)
msg.post(".", "acquire_input_focus")
gui.set_render_order(14)
end
function on_input(self, action_id, action)
if action_id == hash("touch") and action.pressed then
if gui.pick_node(gui.get_node("showpopup2"), action.x, action.y) then
monarch.show("popup2")
elseif gui.pick_node(gui.get_node("closepopup"), action.x, action.y) then
monarch.back()
end
end
end

View File

@ -0,0 +1,39 @@
name: "popup2"
scale_along_z: 0
embedded_instances {
id: "go"
data: "components {\n"
" id: \"popup2\"\n"
" component: \"/example/basic/popup2.gui\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
""
position {
x: 0.0
y: 0.0
z: 0.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale3 {
x: 1.0
y: 1.0
z: 1.0
}
}

385
example/basic/popup2.gui Normal file
View File

@ -0,0 +1,385 @@
script: "/example/basic/popup2.gui_script"
fonts {
name: "example"
font: "/assets/example.font"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 320.0
y: 568.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 400.0
y: 400.0
z: 0.0
w: 1.0
}
color {
x: 0.5019608
y: 0.7019608
z: 0.7019608
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "root"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 0.0
y: 100.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "showpopup2"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_AUTO
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "SHOW POPUP 2"
font: "example"
id: "showtext"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "showpopup2"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 1.0
shadow_alpha: 1.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 40.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "THIS IS POPUP 2"
font: "example"
id: "id"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "root"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 1.0
shadow_alpha: 1.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 0.0
y: -100.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "closepopup"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_AUTO
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "CLOSE"
font: "example"
id: "closetext"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "closepopup"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 1.0
shadow_alpha: 1.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@ -0,0 +1,16 @@
local monarch = require "monarch.monarch"
function init(self)
msg.post(".", "acquire_input_focus")
gui.set_render_order(15)
end
function on_input(self, action_id, action)
if action_id == hash("touch") and action.pressed then
if gui.pick_node(gui.get_node("showpopup2"), action.x, action.y) then
monarch.show("popup2")
elseif gui.pick_node(gui.get_node("closepopup"), action.x, action.y) then
monarch.back()
end
end
end

View File

@ -62,6 +62,9 @@ nodes {
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_AUTO
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
@ -98,7 +101,7 @@ nodes {
blend_mode: BLEND_MODE_ALPHA
text: "SHOW SCREEN 2"
font: "example"
id: "text"
id: "showscreen2text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
@ -125,6 +128,197 @@ nodes {
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 320.0
y: 10.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 40.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "THIS IS SCREEN 1"
font: "example"
id: "id"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_S
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 1.0
shadow_alpha: 1.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 320.0
y: 450.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "showpopup1"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_AUTO
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "SHOW POPUP 1"
font: "example"
id: "showpopup1text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "showpopup1"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 1.0
shadow_alpha: 1.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@ -8,6 +8,8 @@ function on_input(self, action_id, action)
if action_id == hash("touch") and action.pressed then
if gui.pick_node(gui.get_node("showscreen2"), action.x, action.y) then
monarch.show("screen2")
elseif gui.pick_node(gui.get_node("showpopup1"), action.x, action.y) then
monarch.show("popup1")
end
end
end

View File

@ -62,6 +62,9 @@ nodes {
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_AUTO
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
@ -125,6 +128,197 @@ nodes {
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 320.0
y: 10.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 40.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "THIS IS SCREEN 2"
font: "example"
id: "id"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_S
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 1.0
shadow_alpha: 1.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 320.0
y: 450.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "showpopup1"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_AUTO
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "SHOW POPUP 1"
font: "example"
id: "showpopup1text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "showpopup1"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 1.0
shadow_alpha: 1.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT

View File

@ -8,6 +8,8 @@ function on_input(self, action_id, action)
if action_id == hash("touch") and action.pressed then
if gui.pick_node(gui.get_node("backbutton"), action.x, action.y) then
monarch.back()
elseif gui.pick_node(gui.get_node("showpopup1"), action.x, action.y) then
monarch.show("popup1")
end
end
end

View File

@ -0,0 +1,159 @@
name: "slidingwindow"
scale_along_z: 0
embedded_instances {
id: "go"
data: "components {\n"
" id: \"slidingwindow\"\n"
" component: \"/example/slidingwindow/slidingwindow.script\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
""
position {
x: 0.0
y: 0.0
z: 0.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale3 {
x: 1.0
y: 1.0
z: 1.0
}
}
embedded_instances {
id: "window1"
data: "components {\n"
" id: \"screen_proxy\"\n"
" component: \"/monarch/screen_proxy.script\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
" properties {\n"
" id: \"screen_id\"\n"
" value: \"window1\"\n"
" type: PROPERTY_TYPE_HASH\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"collectionproxy\"\n"
" type: \"collectionproxy\"\n"
" data: \"collection: \\\"/example/slidingwindow/window1.collection\\\"\\n"
"exclude: false\\n"
"\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
"}\n"
""
position {
x: 0.0
y: 0.0
z: 0.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale3 {
x: 1.0
y: 1.0
z: 1.0
}
}
embedded_instances {
id: "window2"
data: "components {\n"
" id: \"screen_proxy\"\n"
" component: \"/monarch/screen_proxy.script\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
" properties {\n"
" id: \"screen_id\"\n"
" value: \"window2\"\n"
" type: PROPERTY_TYPE_HASH\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"collectionproxy\"\n"
" type: \"collectionproxy\"\n"
" data: \"collection: \\\"/example/slidingwindow/window2.collection\\\"\\n"
"exclude: false\\n"
"\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
"}\n"
""
position {
x: 0.0
y: 0.0
z: 0.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale3 {
x: 1.0
y: 1.0
z: 1.0
}
}

View File

@ -0,0 +1,28 @@
local monarch = require "monarch.monarch"
function init(self)
monarch.debug()
msg.post("@render:/", "clear_color", { color = vmath.vector4(0.4, 0.6, 0.8,1.0) })
msg.post("#", "init_monarch") -- wait until init() has been called for all screen.script instances
monarch.add_listener()
end
function final(self)
monarch.remove_listener()
end
function on_message(self, message_id, message, sender)
if message_id == hash("init_monarch") then
monarch.show(hash("window1"))
elseif message_id == monarch.SCREEN_TRANSITION_IN_STARTED then
print("Monarch screen transition in started", message.screen)
elseif message_id == monarch.SCREEN_TRANSITION_IN_FINISHED then
print("Monarch screen transition in finished", message.screen)
elseif message_id == monarch.SCREEN_TRANSITION_OUT_STARTED then
print("Monarch screen transition out started", message.screen)
elseif message_id == monarch.SCREEN_TRANSITION_OUT_FINISHED then
print("Monarch screen transition out finished", message.screen)
elseif message_id == monarch.SCREEN_TRANSITION_FAILED then
print("Monarch screen transition failed")
end
end

View File

@ -0,0 +1,39 @@
name: "window1"
scale_along_z: 0
embedded_instances {
id: "go"
data: "components {\n"
" id: \"window1\"\n"
" component: \"/example/slidingwindow/window1.gui\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
""
position {
x: 0.0
y: 0.0
z: 0.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale3 {
x: 1.0
y: 1.0
z: 1.0
}
}

View File

@ -0,0 +1,261 @@
script: "/example/slidingwindow/window1.gui_script"
fonts {
name: "example"
font: "/assets/example.font"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 320.0
y: 568.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 640.0
y: 1136.0
z: 0.0
w: 1.0
}
color {
x: 0.3019608
y: 0.3019608
z: 0.3019608
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "bg"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_STRETCH
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "button"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "bg"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "WINDOW 2"
font: "example"
id: "text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "button"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 1.0
shadow_alpha: 1.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 0.0
y: 338.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 2.0
y: 2.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "WINDOW 1"
font: "example"
id: "title"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "bg"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 1.0
shadow_alpha: 1.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@ -0,0 +1,35 @@
local monarch = require "monarch.monarch"
local transitions = require "monarch.transitions.gui"
function init(self)
msg.post(".", "acquire_input_focus")
local DURATION = 0.3
local transition = transitions.create(gui.get_node("bg"))
.show_in(transitions.slide_in_right, gui.EASING_LINEAR, DURATION, 0)
.show_out(transitions.slide_out_left, gui.EASING_LINEAR, DURATION, 0)
.back_in(transitions.slide_in_left, gui.EASING_LINEAR, DURATION, 0)
.back_out(transitions.slide_out_right, gui.EASING_LINEAR, DURATION, 0)
monarch.on_transition("window1", transition)
monarch.on_focus_changed("window1", function(message_id, message)
if message_id == monarch.FOCUS.GAINED then
print("window1 gained focus")
elseif message_id == monarch.FOCUS.LOST then
print("window1 lost focus")
end
end)
end
function on_input(self, action_id, action)
if action_id == hash("touch") and action.released then
if gui.pick_node(gui.get_node("button"), action.x, action.y) then
monarch.show("window2")
end
end
end
function on_message(self, message_id, message, sender)
monarch.on_message(message_id, message, sender)
end

View File

@ -0,0 +1,39 @@
name: "window2"
scale_along_z: 0
embedded_instances {
id: "go"
data: "components {\n"
" id: \"window2\"\n"
" component: \"/example/slidingwindow/window2.gui\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
""
position {
x: 0.0
y: 0.0
z: 0.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale3 {
x: 1.0
y: 1.0
z: 1.0
}
}

View File

@ -0,0 +1,261 @@
script: "/example/slidingwindow/window2.gui_script"
fonts {
name: "example"
font: "/assets/example.font"
}
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
nodes {
position {
x: 320.0
y: 568.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 640.0
y: 1136.0
z: 0.0
w: 1.0
}
color {
x: 0.3019608
y: 0.3019608
z: 0.3019608
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "bg"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_STRETCH
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_BOX
blend_mode: BLEND_MODE_ALPHA
texture: ""
id: "button"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT
parent: "bg"
layer: ""
inherit_alpha: true
slice9 {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
clipping_mode: CLIPPING_MODE_NONE
clipping_visible: true
clipping_inverted: false
alpha: 1.0
template_node_child: false
size_mode: SIZE_MODE_MANUAL
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 50.0
z: 0.0
w: 1.0
}
color {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "BACK"
font: "example"
id: "text"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "button"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 1.0
shadow_alpha: 1.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
}
nodes {
position {
x: 0.0
y: 338.0
z: 0.0
w: 1.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale {
x: 2.0
y: 2.0
z: 1.0
w: 1.0
}
size {
x: 200.0
y: 100.0
z: 0.0
w: 1.0
}
color {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
type: TYPE_TEXT
blend_mode: BLEND_MODE_ALPHA
text: "WINDOW 2"
font: "example"
id: "title"
xanchor: XANCHOR_NONE
yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER
outline {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
shadow {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
adjust_mode: ADJUST_MODE_FIT
line_break: false
parent: "bg"
layer: ""
inherit_alpha: true
alpha: 1.0
outline_alpha: 1.0
shadow_alpha: 1.0
template_node_child: false
text_leading: 1.0
text_tracking: 0.0
custom_type: 0
enabled: true
visible: true
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512

View File

@ -0,0 +1,27 @@
local monarch = require "monarch.monarch"
local transitions = require "monarch.transitions.gui"
function init(self)
msg.post(".", "acquire_input_focus")
local DURATION = 0.3
local transition = transitions.create(gui.get_node("bg"))
.show_in(transitions.slide_in_right, gui.EASING_LINEAR, DURATION, 0)
.show_out(transitions.slide_out_left, gui.EASING_LINEAR, DURATION, 0)
.back_in(transitions.slide_in_left, gui.EASING_LINEAR, DURATION, 0)
.back_out(transitions.slide_out_right, gui.EASING_LINEAR, DURATION, 0)
monarch.on_transition("window2", transition)
end
function on_input(self, action_id, action)
if action_id == hash("touch") and action.released then
if gui.pick_node(gui.get_node("button"), action.x, action.y) then
monarch.back()
end
end
end
function on_message(self, message_id, message, sender)
monarch.on_message(message_id, message, sender)
end

View File

@ -2,6 +2,7 @@
title = Monarch
version = 0.9
dependencies#0 = https://github.com/britzl/deftest/archive/2.7.0.zip
dependencies#1 = https://github.com/defold/lua-language-server/releases/download/v0.0.3/release.zip
[bootstrap]
main_collection = /example/advanced/advanced.collectionc

View File

@ -79,16 +79,9 @@ end
gui_template = function(gui_script)
return [[script: "]].. gui_script .. [["
background_color {
x: 0.0
y: 0.0
z: 0.0
w: 0.0
}
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
max_nodes: 512
]]
material: "/builtins/materials/gui.material"
adjust_reference: ADJUST_REFERENCE_PARENT
]]
end
gui_script_content = [[local monarch = require "monarch.monarch"
@ -116,43 +109,43 @@ end
collection_template = function(gui_script, name)
return [[name: "]].. name .. [["
scale_along_z: 0
embedded_instances {
id: "go"
data: "components {\n"
" id: \"monarch\"\n"
" component: \"]].. gui_script .. [[\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
"}\n"
""
position {
x: 0.0
y: 0.0
z: 0.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale3 {
x: 1.0
y: 1.0
z: 1.0
}
}
]]
scale_along_z: 0
embedded_instances {
id: "go"
data: "components {\n"
" id: \"monarch\"\n"
" component: \"]].. gui_script .. [[\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
"}\n"
""
position {
x: 0.0
y: 0.0
z: 0.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale3 {
x: 1.0
y: 1.0
z: 1.0
}
}
]]
end

View File

@ -3,16 +3,25 @@ local async = require "monarch.utils.async"
local M = {}
local CONTEXT = hash("monarch_context")
local PROXY_LOADED = hash("proxy_loaded")
local PROXY_UNLOADED = hash("proxy_unloaded")
local WAITFOR_COWAIT = hash("waitfor_cowait")
local WAITFOR_CONTEXT = hash("waitfor_monarch_context")
local WAITFOR_PROXY_LOADED = hash("waitfor_proxy_loaded")
local WAITFOR_PROXY_UNLOADED = hash("waitfor_proxy_unloaded")
local WAITFOR_TRANSITION_DONE = hash("waitfor_transition_done")
local RELEASE_INPUT_FOCUS = hash("release_input_focus")
local ACQUIRE_INPUT_FOCUS = hash("acquire_input_focus")
local ASYNC_LOAD = hash("async_load")
local UNLOAD = hash("unload")
local ENABLE = hash("enable")
local DISABLE = hash("disable")
local MSG_CONTEXT = hash("monarch_context")
local MSG_PROXY_LOADED = hash("proxy_loaded")
local MSG_PROXY_UNLOADED = hash("proxy_unloaded")
local MSG_LAYOUT_CHANGED = hash("layout_changed")
local MSG_RELEASE_INPUT_FOCUS = hash("release_input_focus")
local MSG_ACQUIRE_INPUT_FOCUS = hash("acquire_input_focus")
local MSG_ASYNC_LOAD = hash("async_load")
local MSG_UNLOAD = hash("unload")
local MSG_ENABLE = hash("enable")
local MSG_DISABLE = hash("disable")
local DEPRECATED = hash("__DEPRECATED__")
-- transition messages
M.TRANSITION = {}
@ -81,10 +90,13 @@ local function assign(to, from)
return to
end
local function cowait(delay)
local function cowait(screen, delay)
log("cowait()", screen.id, delay)
local co = coroutine.running()
assert(co, "You must run this from within a coroutine")
screen.wait_for = WAITFOR_COWAIT
timer.delay(delay, false, function()
screen.wait_for = nil
assert(coroutine.resume(co))
end)
coroutine.yield()
@ -108,7 +120,7 @@ process_queue = function()
log("queue() busy")
return
end
action = table.remove(queue, 1)
local action = table.remove(queue, 1)
if not action then
log("queue() empty")
return
@ -134,23 +146,49 @@ local function notify_transition_listeners(message_id, message)
end
end
local function screen_from_proxy(proxy)
for _,screen in pairs(screens) do
if screen.proxy == proxy then
return screen
local function find_screen(url_to_find)
local function find(url)
for _,screen in pairs(screens) do
if screen.script == url or screen.proxy == url then
return screen
end
end
end
return find(msg.url()) or find(url_to_find)
end
local function screen_from_script()
local url = msg.url()
for _,screen in pairs(screens) do
if screen.script == url then
return screen
local function find_transition_screen(url_to_find)
local function find(url)
for _,screen in pairs(screens) do
if screen.transition_url == url or screen.script == url or screen.proxy == url then
return screen
end
end
end
return find(msg.url()) or find(url_to_find)
end
local function find_focus_screen(url_to_find)
local function find(url)
for _,screen in pairs(screens) do
if screen.focus_url == url or screen.script == url or screen.proxy == url then
return screen
end
end
end
return find(msg.url()) or find(url_to_find)
end
local function find_post_receiver_screen(url_to_find)
local function find(url)
for _,screen in pairs(screens) do
if screen.receiver_url == url or screen.script == url or screen.proxy == url then
return screen
end
end
end
return find(msg.url()) or find(url_to_find)
end
--- Check if a screen exists in the current screen stack
-- @param id (string|hash)
@ -190,6 +228,17 @@ function M.is_visible(id)
end
--- Check if a screen is loaded
-- @param id (string|hash)
-- @return true if the screen is loaded
function M.is_loaded(id)
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)))
return screens[id].loaded
end
--- Check if a screen is a popup
-- @param id Screen id
-- @return true if the screen is a popup
@ -234,12 +283,6 @@ end
-- keep input focus when below a popup
-- * others_keep_input_focus_when_below_screen - If screens below this
-- screen should keep input focus
-- * transition_url - URL to a script that is responsible for the
-- screen transitions
-- * focus_url - URL to a script that is to be notified of focus
-- lost/gained events
-- * receiver_url - URL to a script that is to receive messages sent
-- using monarch.send()
-- * auto_preload - true if the screen should be automatically preloaded
function M.register_proxy(id, proxy, settings)
assert(proxy, "You must provide a collection proxy URL")
@ -249,6 +292,15 @@ function M.register_proxy(id, proxy, settings)
screen.focus_url = settings and settings.focus_url
screen.receiver_url = settings and settings.receiver_url
screen.auto_preload = settings and settings.auto_preload
if screen.transition_url.fragment == DEPRECATED then
screen.transition_url = nil
end
if screen.focus_url.fragment == DEPRECATED then
screen.focus_url = nil
end
if screen.receiver_url.fragment == DEPRECATED then
screen.receiver_url = nil
end
if screen.auto_preload then
M.preload(id)
end
@ -271,10 +323,6 @@ M.register = M.register_proxy
-- keep input focus when below a popup
-- * others_keep_input_focus_when_below_screen - If screens below this
-- screen should keep input focus
-- * transition_id - Id of the game object in the collection that is responsible
-- for the screen transitions
-- * focus_id - Id of the game object in the collection that is to be notified
-- of focus lost/gained events
-- * auto_preload - true if the screen should be automatically preloaded
function M.register_factory(id, factory, settings)
assert(factory, "You must provide a collection factory URL")
@ -283,6 +331,13 @@ function M.register_factory(id, factory, settings)
screen.transition_id = settings and settings.transition_id
screen.focus_id = settings and settings.focus_id
screen.auto_preload = settings and settings.auto_preload
if screen.transition_id == DEPRECATED then
screen.transition_id = nil
end
if screen.focus_id == DEPRECATED then
screen.focus_id = nil
end
if screen.auto_preload then
M.preload(id)
end
@ -298,16 +353,26 @@ 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
screen.unregistered = true
if screen.wait_for then
assert(coroutine.resume(screen.co))
end
end
local function acquire_input(screen)
log("acquire_input()", screen.id)
if not screen.input then
if screen.proxy then
msg.post(screen.script, ACQUIRE_INPUT_FOCUS)
msg.post(screen.script, MSG_ACQUIRE_INPUT_FOCUS)
elseif screen.factory then
for id,instance in pairs(screen.factory_ids) do
msg.post(instance, ACQUIRE_INPUT_FOCUS)
msg.post(instance, MSG_ACQUIRE_INPUT_FOCUS)
end
end
screen.input = true
@ -325,10 +390,10 @@ local function release_input(screen, next_screen)
local release_focus = not keep_if_next_is_popup and not keep_when_below_next
if release_focus then
if screen.proxy then
msg.post(screen.script, RELEASE_INPUT_FOCUS)
msg.post(screen.script, MSG_RELEASE_INPUT_FOCUS)
elseif screen.factory then
for id,instance in pairs(screen.factory_ids) do
msg.post(instance, RELEASE_INPUT_FOCUS)
msg.post(instance, MSG_RELEASE_INPUT_FOCUS)
end
end
screen.input = false
@ -338,22 +403,25 @@ end
local function change_context(screen)
log("change_context()", screen.id)
screen.wait_for = CONTEXT
msg.post(screen.script, CONTEXT, { id = screen.id })
screen.wait_for = WAITFOR_CONTEXT
msg.post(screen.script, MSG_CONTEXT, { id = screen.id })
coroutine.yield()
screen.wait_for = nil
end
local function unload(screen, force)
if screen.unregistered then return end
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, MSG_DISABLE)
screen.loaded = false
end
screen.preloaded = true
else
screen.wait_for = PROXY_UNLOADED
msg.post(screen.proxy, UNLOAD)
screen.wait_for = WAITFOR_PROXY_UNLOADED
msg.post(screen.proxy, MSG_UNLOAD)
coroutine.yield()
screen.loaded = false
screen.preloaded = false
@ -362,7 +430,9 @@ local function unload(screen, force)
elseif screen.factory then
log("unload() factory", screen.id)
for id, instance in pairs(screen.factory_ids) do
go.delete(instance)
if go.exists(instance) then
go.delete(instance)
end
end
screen.factory_ids = nil
if screen.auto_preload and not force then
@ -377,8 +447,8 @@ local function unload(screen, force)
-- we need to wait here in case the unloaded screen contained any screens
-- if this is the case we need to let these sub-screens have their final()
-- functions called so that they have time to call unregister()
cowait(0)
cowait(0)
cowait(screen, 0)
cowait(screen, 0)
end
@ -394,16 +464,19 @@ local function preload(screen)
screen.preloading = true
if screen.proxy then
log("preload() proxy")
local missing_resources = collectionproxy.missing_resources(screen.proxy)
if #missing_resources > 0 then
if M.has_missing_resources(screen.id) then
local error_message = ("preload() collection proxy %s is missing resources"):format(tostring(screen.id))
log(error_message)
screen.preloading = false
return false, error_message
end
screen.wait_for = PROXY_LOADED
msg.post(screen.proxy, ASYNC_LOAD)
screen.wait_for = WAITFOR_PROXY_LOADED
msg.post(screen.proxy, MSG_ASYNC_LOAD)
coroutine.yield()
screen.wait_for = nil
if screen.unregistered then
return false, "Screen was unregistered while loading"
end
elseif screen.factory then
log("preload() factory")
if collectionfactory.get_status(screen.factory) == collectionfactory.STATUS_UNLOADED then
@ -411,6 +484,9 @@ local function preload(screen)
assert(coroutine.resume(screen.co))
end)
coroutine.yield()
if screen.unregistered then
return false, "Screen was unregistered while loading"
end
end
if collectionfactory.get_status(screen.factory) ~= collectionfactory.STATUS_LOADED then
@ -442,11 +518,15 @@ local function load(screen)
end
if screen.proxy then
msg.post(screen.proxy, ENABLE)
msg.post(screen.proxy, MSG_ENABLE)
elseif screen.factory then
screen.factory_ids = collectionfactory.create(screen.factory)
screen.transition_url = screen.factory_ids[screen.transition_id]
screen.focus_url = screen.factory_ids[screen.focus_id]
if screen.transition_id then
screen.transition_url = screen.factory_ids[screen.transition_id]
end
if screen.focus_id then
screen.focus_url = screen.factory_ids[screen.focus_id]
end
end
screen.loaded = true
screen.preloaded = false
@ -455,8 +535,9 @@ end
local function transition(screen, message_id, message, wait)
log("transition()", screen.id)
if screen.unregistered then return end
if screen.transition_url then
screen.wait_for = M.TRANSITION.DONE
screen.wait_for = WAITFOR_TRANSITION_DONE
msg.post(screen.transition_url, message_id, message)
if wait then
coroutine.yield()
@ -478,14 +559,15 @@ end
local function focus_lost(screen, next_screen)
log("focus_lost()", screen.id)
if screen.unregistered then return end
if screen.focus_url then
msg.post(screen.focus_url, M.FOCUS.LOST, { id = next_screen and next_screen.id })
-- if there's no transition on the screen losing focus and it gets
-- unloaded this will happen before the focus_lost message reaches
-- the focus_url
-- we add a delay to ensure the message queue has time to be processed
cowait(0)
cowait(0)
cowait(screen, 0)
cowait(screen, 0)
else
log("focus_lost() no focus url - ignoring")
end
@ -605,6 +687,8 @@ local function show_in(screen, previous_screen, reload, add_to_stack, wait_for_t
notify_transition_listeners(M.SCREEN_TRANSITION_FAILED, { screen = screen.id })
return
end
-- wait one frame so that the init() of any script have time to run before starting transitions
cowait(screen, 0)
reset_timestep(screen)
transition(screen, M.TRANSITION.SHOW_IN, { previous_screen = previous_screen and previous_screen.id }, wait_for_transition)
screen.visible = true
@ -629,6 +713,8 @@ local function back_in(screen, previous_screen, wait_for_transition, cb)
notify_transition_listeners(M.SCREEN_TRANSITION_FAILED, { screen = screen.id })
return
end
-- wait one frame so that the init() of any script have time to run before starting transitions
cowait(screen, 0)
reset_timestep(screen)
if previous_screen and not previous_screen.popup then
transition(screen, M.TRANSITION.BACK_IN, { previous_screen = previous_screen.id }, wait_for_transition)
@ -645,15 +731,15 @@ local function back_out(screen, next_screen, wait_for_transition, cb)
log("back_out()", screen.id)
assert(wait_for_transition ~= nil)
run_coroutine(screen, cb, function()
notify_transition_listeners(M.SCREEN_TRANSITION_OUT_STARTED, { screen = screen.id, next_screen = next_screen and next_screen.id })
active_transition_count = active_transition_count + 1
notify_transition_listeners(M.SCREEN_TRANSITION_OUT_STARTED, { screen = screen.id, next_screen = next_screen and next_screen.id })
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
@ -793,13 +879,10 @@ function M.show(id, options, data, cb)
show_in(screen, top, options and options.reload, add_to_stack, WAIT_FOR_TRANSITION, callbacks.track())
else
-- show screen
local cb = callbacks.track()
show_in(screen, top, options and options.reload, add_to_stack, DO_NOT_WAIT_FOR_TRANSITION, function()
if add_to_stack and top and not top.popup then
show_out(top, screen, WAIT_FOR_TRANSITION, callbacks.track())
end
cb()
end)
show_in(screen, top, options and options.reload, add_to_stack, WAIT_FOR_TRANSITION, callbacks.track())
if add_to_stack and top and not top.popup then
show_out(top, screen, WAIT_FOR_TRANSITION, callbacks.track())
end
end
callbacks.when_done(function()
@ -842,7 +925,7 @@ function M.hide(id, cb)
log("hide() you can only hide the screen at the top of the stack", id)
return false
end
return M.back(id, cb)
return M.back(nil, nil, cb)
else
log("hide() queuing action", id)
queue_action(function(action_done, action_error)
@ -879,7 +962,7 @@ function M.clear(cb)
local top = stack[#stack]
while top and top.visible do
stack[#stack] = nil
await(back_out, top, screen, WAIT_FOR_TRANSITION, resume)
await(back_out, top, stack[#stack - 1], WAIT_FOR_TRANSITION, resume)
top = stack[#stack]
end
@ -895,21 +978,27 @@ end
-- Go back to the previous screen in the stack.
-- @param options (table) - Table with options when backing out from the screen (can be nil).
-- Valid values:
-- * sequential - Set to true to wait for the current screen to hide itself out before starting the
-- back in transition even when transitioning to a different scene ID.
-- @param data (*) - Optional data to set for the previous screen
-- @param cb (function) - Optional callback to invoke when the previous screen is visible again
function M.back(data, cb)
function M.back(options, data, cb)
log("back() queuing action")
queue_action(function(action_done)
local callbacks = callback_tracker()
local back_cb = callbacks.track()
local screen = table.remove(stack)
if screen then
log("back()", screen.id)
local top = stack[#stack]
-- if we go back to the same screen we need to first hide it
-- and wait until it is hidden before we show it again
if top and screen.id == top.id then
local same_screen = top and top.id == screen.id
if same_screen or (options and options.sequential) then
local back_cb = callbacks.track()
back_out(screen, top, WAIT_FOR_TRANSITION, function()
if data then
top.data = data
@ -921,11 +1010,22 @@ 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
local back_cb = callbacks.track()
back_out(screen, top, WAIT_FOR_TRANSITION, function()
back_in(top, screen, WAIT_FOR_TRANSITION, back_cb)
end)
else
back_in(top, screen, WAIT_FOR_TRANSITION, callbacks.track())
back_out(screen, top, WAIT_FOR_TRANSITION, callbacks.track())
end
else
back_out(screen, top, WAIT_FOR_TRANSITION, back_cb)
back_out(screen, top, WAIT_FOR_TRANSITION, callbacks.track())
end
end
end
@ -979,12 +1079,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 +1102,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)
@ -1021,6 +1132,20 @@ function M.preload(id, cb)
return true -- return true for legacy reasons (before queue existed)
end
--- Check if a screen has missing resources, always returns false for factory
-- @param id (string|hash) - Id of the screen to preload
function M.has_missing_resources(id)
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)))
local screen = screens[id]
if screen.proxy then
local missing_resources = collectionproxy.missing_resources(screen.proxy)
return #missing_resources > 0
end
return false
end
--- Unload a preloaded monarch screen
-- @param id (string|hash) - Id of the screen to unload
@ -1057,7 +1182,7 @@ function M.unload(id, cb)
end
run_coroutine(screen, when_unloaded, function()
change_context(screen)
unload(screen)
unload(screen, true)
end)
end)
return true -- return true for legacy reasons (before queue existed)
@ -1072,8 +1197,8 @@ end
-- @return error (string|nil) Error message if unable to send message
function M.post(id, message_id, message)
assert(id, "You must provide a screen id")
if not M.is_visible(id) then
return false, "Unable to post message to screen if it isn't visible"
if not M.is_loaded(id) then
return false, "Unable to post message to screen if it isn't loaded"
end
assert(message_id, "You must provide a message_id")
@ -1081,47 +1206,69 @@ function M.post(id, message_id, message)
assert(screens[id], ("There is no screen registered with id %s"):format(tostring(id)))
local screen = screens[id]
if screen.proxy then
if screen.receiver_url then
log("post() sending message to", screen.receiver_url)
msg.post(screen.receiver_url, message_id, message)
else
return false, "Unable to post message since screen has no receiver url specified"
end
if screen.receiver_url then
log("post() sending message to", screen.receiver_url)
msg.post(screen.receiver_url, message_id, message)
else
for id,instance in pairs(screen.factory_ids) do
msg.post(instance, message_id, message)
end
return false, "Unable to post message since screen has no receiver url specified. Set one using monarch.on_post()."
end
return true
end
function M.on_message(message_id, message, sender)
if message_id == PROXY_LOADED then
local screen = screen_from_proxy(sender)
if message_id == MSG_PROXY_LOADED then
local screen = find_screen(sender)
assert(screen, "Unable to find screen for loaded proxy")
if screen.wait_for == PROXY_LOADED then
if screen.wait_for == WAITFOR_PROXY_LOADED then
assert(coroutine.resume(screen.co))
end
elseif message_id == PROXY_UNLOADED then
local screen = screen_from_proxy(sender)
elseif message_id == MSG_PROXY_UNLOADED then
local screen = find_screen(sender)
assert(screen, "Unable to find screen for unloaded proxy")
if screen.wait_for == PROXY_UNLOADED then
if screen.wait_for == WAITFOR_PROXY_UNLOADED then
assert(coroutine.resume(screen.co))
end
elseif message_id == CONTEXT then
local screen = screen_from_script()
elseif message_id == MSG_CONTEXT then
local screen = find_screen(sender)
assert(screen, "Unable to find screen for current script url")
if screen.wait_for == CONTEXT then
if screen.wait_for == WAITFOR_CONTEXT then
assert(coroutine.resume(screen.co))
end
elseif message_id == M.TRANSITION.DONE then
local screen = screen_from_script()
assert(screen, "Unable to find screen for current script url")
if screen.wait_for == M.TRANSITION.DONE then
local screen = find_transition_screen(sender)
assert(screen, "Unable to find screen for transition")
if screen.wait_for == WAITFOR_TRANSITION_DONE then
assert(coroutine.resume(screen.co))
end
elseif message_id == M.TRANSITION.SHOW_IN
or message_id == M.TRANSITION.SHOW_OUT
or message_id == M.TRANSITION.BACK_IN
or message_id == M.TRANSITION.BACK_OUT
then
local screen = find_transition_screen(sender)
assert(screen, "Unable to find screen for transition")
if screen.transition_fn then
screen.transition_fn(message_id, message, sender)
end
elseif message_id == MSG_LAYOUT_CHANGED then
local screen = find_screen(sender)
if screen and screen.transition_fn then
screen.transition_fn(message_id, message, sender)
end
elseif message_id == M.FOCUS.GAINED
or message_id == M.FOCUS.LOST
then
local screen = find_focus_screen(sender)
assert(screen, "Unable to find screen for focus change")
if screen.focus_fn then
screen.focus_fn(message_id, message, sender)
end
else
local screen = find_post_receiver_screen(sender)
if screen and screen.receiver_fn then
screen.receiver_fn(message_id, message, sender)
end
end
end
@ -1168,8 +1315,71 @@ function M.set_timestep_below_popup(id, timestep)
end
---
-- Set a function to call when a transition should be started
-- The function will receive (message_id, message, sender)
-- IMPORTANT! You must call monarch.on_message() from the same script as
-- this function was called
-- @param id Screen id to associate transition with
-- @param fn Transition handler function
function M.on_transition(id, fn)
assert(id, "You must provide a screen id")
assert(fn, "You must provide a transition function")
id = tohash(id)
assert(screens[id], ("There is no screen registered with id %s"):format(tostring(id)))
local screen = screens[id]
screen.transition_url = msg.url()
screen.transition_fn = fn
end
---
-- Set a function to call when a screen gains or loses focus
-- The function will receive (message_id, message, sender)
-- IMPORTANT! You must call monarch.on_message() from the same script as
-- this function was called
-- @param id Screen id to associate focus listener function with
-- @param fn Focus listener function
function M.on_focus_changed(id, fn)
assert(id, "You must provide a screen id")
assert(fn, "You must provide a focus change function")
id = tohash(id)
assert(screens[id], ("There is no screen registered with id %s"):format(tostring(id)))
local screen = screens[id]
screen.focus_url = msg.url()
screen.focus_fn = fn
end
---
-- Set either a function to be called when msg.post() is called on a specific
-- screen or a URL where the message is sent.
-- IMPORTANT! If you provide a function you must also make sure to call
-- monarch.on_message(message_id, message, sender) from the same script as
-- this function was called.
-- @param id Screen id to associate the message listener function with
-- @param fn_or_url The function to call or URL to send message to
function M.on_post(id, fn_or_url)
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)))
local screen = screens[id]
local t = type(fn_or_url)
if t == "function" then
screen.receiver_fn = fn_or_url
screen.receiver_url = msg.url()
elseif t == "userdata" or t == "string" then
screen.receiver_fn = nil
screen.receiver_url = fn_or_url
else
screen.receiver_fn = nil
screen.receiver_url = msg.url()
end
end
local empty_hash = hash("")
local function url_to_key(url)
return (url.socket or hash("")) .. (url.path or hash("")) .. (url.fragment or hash(""))
return (url.socket or empty_hash) .. (url.path or empty_hash) .. (url.fragment or empty_hash)
end

View File

@ -6,8 +6,8 @@ go.property("popup", false)
go.property("popup_on_popup", false)
go.property("screen_keeps_input_focus_when_below_popup", false)
go.property("others_keep_input_focus_when_below_screen", false)
go.property("transition_id", hash(""))
go.property("focus_id", hash(""))
go.property("transition_id", hash("__DEPRECATED__"))
go.property("focus_id", hash("__DEPRECATED__"))
go.property("preload", false)

View File

@ -7,9 +7,9 @@ go.property("popup_on_popup", false)
go.property("timestep_below_popup", 1)
go.property("screen_keeps_input_focus_when_below_popup", false)
go.property("others_keep_input_focus_when_below_screen", false)
go.property("transition_url", msg.url())
go.property("focus_url", msg.url())
go.property("receiver_url", msg.url())
go.property("transition_url", msg.url("#__DEPRECATED__"))
go.property("focus_url", msg.url("#__DEPRECATED__"))
go.property("receiver_url", msg.url("#__DEPRECATED__"))
go.property("preload", false)

View File

@ -20,10 +20,10 @@ local LAYOUT_CHANGED = hash("layout_changed")
function M.window_resized(width, height)
WIDTH = width
HEIGHT = height
LEFT = vmath.vector3(-WIDTH * 2, 0, 0)
RIGHT = vmath.vector3(WIDTH * 2, 0, 0)
TOP = vmath.vector3(0, HEIGHT * 2, 0)
BOTTOM = vmath.vector3(0, - HEIGHT * 2, 0)
LEFT = vmath.vector3(-WIDTH, 0, 0)
RIGHT = vmath.vector3(WIDTH, 0, 0)
TOP = vmath.vector3(0, HEIGHT, 0)
BOTTOM = vmath.vector3(0, - HEIGHT, 0)
end
M.window_resized(tonumber(sys.get_config("display.width")), tonumber(sys.get_config("display.height")))
@ -173,10 +173,10 @@ local function create()
end
local function start_transition(transition_id, url)
url = url or msg.url()
local t = transitions[transition_id]
table.insert(t.urls, url)
if t.in_progress_count == 0 then
table.insert(t.urls, msg.url())
current_transition = t
current_transition.id = transition_id
if #t.transitions > 0 then
@ -254,7 +254,11 @@ local function create()
return instance
end
return instance
return setmetatable(instance, {
__call = function(t, ...)
return instance.handle(...)
end
})
end
function M.create(node)

View File

@ -14,7 +14,7 @@ function M.create()
local function invoke_if_done()
if all_callbacks_done then
print("Warning: The same callback will be invoked twice from the callback tracker!", id or "")
print("Warning: The same callback will be invoked twice from the callback tracker!")
end
if callback_count == 0 and callback then
all_callbacks_done = true
@ -52,6 +52,6 @@ end
return setmetatable(M, {
__call = function(_, ...)
return M.create(...)
return M.create()
end
})

2
test.settings Normal file
View File

@ -0,0 +1,2 @@
[bootstrap]
main_collection = /test/test.collectionc

View File

@ -1,5 +1,11 @@
local monarch
function init(self)
print("init - screen1")
monarch = require "monarch.monarch"
print("init - screen1", msg.url())
monarch.on_post("screen1", function(message_id, message, sender)
_G.screen1_on_post = message or true
end)
end
function final(self)
@ -7,7 +13,8 @@ function final(self)
end
function on_message(self, message_id, message, sender)
monarch.on_message(message_id, message, sender)
if message_id == hash("foobar") then
_G.screen1_foobar = message or true
_G.screen1_on_message = message or true
end
end

View File

@ -1,5 +1,11 @@
local monarch
function init(self)
print("init - screen2")
monarch = require "monarch.monarch"
print("init - screen2", msg.url())
monarch.on_post("screen2", function(message_id, message, sender)
_G.screen2_on_post = message or true
end)
end
function final(self)
@ -7,7 +13,8 @@ function final(self)
end
function on_message(self, message_id, message, sender)
monarch.on_message(message_id, message, sender)
if message_id == hash("foobar") then
_G.screen2_foobar = message or true
_G.screen2_on_message = message or true
end
end

View File

@ -26,6 +26,8 @@ embedded_instances {
" value: \"screen1:/go\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"collectionproxy\"\n"
@ -84,12 +86,15 @@ embedded_instances {
" value: \"screen2\"\n"
" type: PROPERTY_TYPE_HASH\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"collectionfactory\"\n"
" type: \"collectionfactory\"\n"
" data: \"prototype: \\\"/test/data/screen2.collection\\\"\\n"
"load_dynamically: false\\n"
"dynamic_prototype: false\\n"
"\"\n"
" position {\n"
" x: 0.0\n"
@ -147,6 +152,8 @@ embedded_instances {
" value: \"true\"\n"
" type: PROPERTY_TYPE_BOOLEAN\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"collectionproxy\"\n"
@ -215,6 +222,8 @@ embedded_instances {
" value: \"true\"\n"
" type: PROPERTY_TYPE_BOOLEAN\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"collectionproxy\"\n"
@ -278,6 +287,8 @@ embedded_instances {
" value: \"transition1:/go\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"collectionproxy\"\n"
@ -376,12 +387,15 @@ embedded_instances {
" value: \"background\"\n"
" type: PROPERTY_TYPE_HASH\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"collectionfactory\"\n"
" type: \"collectionfactory\"\n"
" data: \"prototype: \\\"/test/data/background.collection\\\"\\n"
"load_dynamically: false\\n"
"dynamic_prototype: false\\n"
"\"\n"
" position {\n"
" x: 0.0\n"
@ -439,12 +453,15 @@ embedded_instances {
" value: \"true\"\n"
" type: PROPERTY_TYPE_BOOLEAN\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"collectionfactory\"\n"
" type: \"collectionfactory\"\n"
" data: \"prototype: \\\"/test/data/screen_preload.collection\\\"\\n"
"load_dynamically: false\\n"
"dynamic_prototype: false\\n"
"\"\n"
" position {\n"
" x: 0.0\n"
@ -502,6 +519,8 @@ embedded_instances {
" value: \"focus1:/go#focus1\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"collectionproxy\"\n"

View File

@ -64,5 +64,17 @@ function M.last(url)
return messages[#messages]
end
function M.filter(url, fn)
local t = {}
local messages = M.messages(url)
for i=1,#messages do
local message = messages[i]
if fn(message) then
t[#t + 1] = message
end
end
return t
end
return M

View File

@ -16,12 +16,15 @@ embedded_instances {
" z: 0.0\n"
" w: 1.0\n"
" }\n"
" property_decls {\n"
" }\n"
"}\n"
"embedded_components {\n"
" id: \"screensfactory\"\n"
" type: \"collectionfactory\"\n"
" data: \"prototype: \\\"/test/data/screens.collection\\\"\\n"
"load_dynamically: false\\n"
"dynamic_prototype: false\\n"
"\"\n"
" position {\n"
" x: 0.0\n"

View File

@ -12,7 +12,6 @@ local FOCUS1 = hash("focus1")
local BACKGROUND = hash("background")
local POPUP1 = hash("popup1")
local POPUP2 = hash("popup2")
local FOOBAR = hash("foobar")
local TRANSITION1 = hash("transition1")
local function check_stack(expected_screens)
@ -156,6 +155,17 @@ return function()
assert(wait_until_visible(POPUP1))
end)
it("should be able to tell if a screen is loaded or not", function()
assert(not monarch.is_loaded(SCREEN1))
monarch.show(SCREEN1)
assert(wait_until_visible(SCREEN1))
assert(monarch.is_loaded(SCREEN1))
monarch.hide(SCREEN1)
assert(wait_until_hidden(SCREEN1))
assert(not monarch.is_loaded(SCREEN1))
end)
it("should be able to show a screen without adding it to the stack", function()
monarch.show(BACKGROUND, { no_stack = true })
assert(wait_until_visible(BACKGROUND), "Background was never shown")
@ -220,7 +230,7 @@ return function()
assert(monarch.data(SCREEN2) == data2, "Expected data on screen2 doesn't match actual data")
local data_back = { going = "back" }
monarch.back(data_back)
monarch.back(nil, data_back)
assert(wait_until_visible(SCREEN1))
assert(monarch.data(SCREEN1) == data_back, "Expected data on screen1 doesn't match actual data")
@ -378,6 +388,20 @@ return function()
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
@ -394,43 +418,37 @@ return function()
monarch.show(SCREEN1)
assert(wait_until_not_busy())
assert(mock_msg.messages(URL1)[1].message_id == monarch.SCREEN_TRANSITION_IN_STARTED)
assert(mock_msg.messages(URL1)[1].message.screen == SCREEN1)
assert(mock_msg.messages(URL2)[1].message_id == monarch.SCREEN_TRANSITION_IN_STARTED)
assert(mock_msg.messages(URL2)[1].message.screen == SCREEN1)
assert(mock_msg.messages(URL1)[2].message_id == monarch.SCREEN_TRANSITION_IN_FINISHED)
assert(mock_msg.messages(URL1)[2].message.screen == SCREEN1)
assert(mock_msg.messages(URL2)[2].message_id == monarch.SCREEN_TRANSITION_IN_FINISHED)
assert(mock_msg.messages(URL2)[2].message.screen == SCREEN1)
monarch.remove_listener(URL2)
monarch.show(SCREEN2)
assert(wait_until_not_busy())
assert(#mock_msg.messages(URL1) == 6)
assert(#mock_msg.messages(URL2) == 2)
assert(mock_msg.messages(URL1)[3].message_id == monarch.SCREEN_TRANSITION_IN_STARTED)
assert(mock_msg.messages(URL1)[3].message.screen == SCREEN2)
assert(mock_msg.messages(URL1)[4].message_id == monarch.SCREEN_TRANSITION_IN_FINISHED)
assert(mock_msg.messages(URL1)[4].message.screen == SCREEN2)
assert(mock_msg.messages(URL1)[5].message_id == monarch.SCREEN_TRANSITION_OUT_STARTED)
assert(mock_msg.messages(URL1)[5].message.screen == SCREEN1)
assert(mock_msg.messages(URL1)[6].message_id == monarch.SCREEN_TRANSITION_OUT_FINISHED)
assert(mock_msg.messages(URL1)[6].message.screen == SCREEN1)
monarch.back()
assert(wait_until_not_busy())
assert(#mock_msg.messages(URL1) == 10)
assert(#mock_msg.messages(URL2) == 2)
assert(mock_msg.messages(URL1)[7].message_id == monarch.SCREEN_TRANSITION_IN_STARTED)
assert(mock_msg.messages(URL1)[7].message.screen == SCREEN1)
assert(mock_msg.messages(URL1)[8].message_id == monarch.SCREEN_TRANSITION_IN_FINISHED)
assert(mock_msg.messages(URL1)[8].message.screen == SCREEN1)
assert(mock_msg.messages(URL1)[9].message_id == monarch.SCREEN_TRANSITION_OUT_STARTED)
assert(mock_msg.messages(URL1)[9].message.screen == SCREEN2)
assert(mock_msg.messages(URL1)[10].message_id == monarch.SCREEN_TRANSITION_OUT_FINISHED)
assert(mock_msg.messages(URL1)[10].message.screen == SCREEN2)
local messages = mock_msg.filter(URL1, function(m)
return m.message.screen == SCREEN1
end)
assert(messages[1].message_id == monarch.SCREEN_TRANSITION_IN_STARTED)
assert(messages[2].message_id == monarch.SCREEN_TRANSITION_IN_FINISHED)
assert(messages[3].message_id == monarch.SCREEN_TRANSITION_OUT_STARTED)
assert(messages[4].message_id == monarch.SCREEN_TRANSITION_OUT_FINISHED)
assert(messages[5].message_id == monarch.SCREEN_TRANSITION_IN_STARTED)
assert(messages[6].message_id == monarch.SCREEN_TRANSITION_IN_FINISHED)
messages = mock_msg.filter(URL2, function(m)
return m.message.screen == SCREEN1
end)
assert(messages[1].message_id == monarch.SCREEN_TRANSITION_IN_STARTED)
assert(messages[2].message_id == monarch.SCREEN_TRANSITION_IN_FINISHED)
messages = mock_msg.filter(URL1, function(m)
return m.message.screen == SCREEN2
end)
assert(messages[1].message_id == monarch.SCREEN_TRANSITION_IN_STARTED)
assert(messages[2].message_id == monarch.SCREEN_TRANSITION_IN_FINISHED)
assert(messages[3].message_id == monarch.SCREEN_TRANSITION_OUT_STARTED)
assert(messages[4].message_id == monarch.SCREEN_TRANSITION_OUT_FINISHED)
end)
it("should be able to show a screen even while it is preloading", function()
@ -477,49 +495,56 @@ return function()
it("should be able to post messages without message data to visible screens", function()
_G.screen1_foobar = nil
_G.screen2_foobar = nil
_G.screen1_on_message = nil
_G.screen1_on_post = nil
_G.screen2_on_message = nil
_G.screen2_on_post = nil
-- proxy screen
monarch.show(SCREEN1)
wait_until_visible(SCREEN1)
assert(monarch.post(SCREEN1, "foobar"), "Expected monarch.post() to return true")
cowait(0.1)
assert(_G.screen1_foobar, "Screen1 never received a message")
assert(_G.screen1_on_message, "Screen1 never received a message")
assert(_G.screen1_on_post, "Screen1 never received a callback")
-- factory screen
monarch.show(SCREEN2)
wait_until_visible(SCREEN2)
assert(monarch.post(SCREEN2, "foobar"), "Expected monarch.post() to return true")
cowait(0.1)
assert(_G.screen2_foobar, "Screen2 never received a message")
assert(_G.screen2_on_message, "Screen2 never received a message")
assert(_G.screen2_on_post, "Screen2 never received a callback")
end)
it("should be able to post messages with message data to visible screens", function()
_G.screen1_foobar = nil
_G.screen2_foobar = nil
_G.screen1_on_message = nil
_G.screen1_on_post = nil
_G.screen2_on_message = nil
_G.screen2_on_post = nil
-- proxy screen
monarch.show(SCREEN1)
wait_until_visible(SCREEN1)
assert(monarch.post(SCREEN1, "foobar", { foo = "bar" }), "Expected monarch.post() to return true")
cowait(0.1)
assert(_G.screen1_foobar, "Screen1 never received a message")
assert(_G.screen1_foobar.foo == "bar", "Screen1 never received message data")
assert(_G.screen1_on_message, "Screen1 never received a message")
assert(_G.screen1_on_message.foo == "bar", "Screen1 never received message data")
-- factory screen
monarch.show(SCREEN2)
wait_until_visible(SCREEN2)
assert(monarch.post(SCREEN2, "foobar", { foo = "bar" }), "Expected monarch.post() to return true")
cowait(0.1)
assert(_G.screen2_foobar, "Screen2 never received a message")
assert(_G.screen2_foobar.foo == "bar", "Screen2 never received message data")
assert(_G.screen2_on_message, "Screen2 never received a message")
assert(_G.screen2_on_message.foo == "bar", "Screen2 never received message data")
end)
it("should not be able to post messages to hidden screens", function()
_G.screen1_foobar = nil
_G.screen1_on_message = nil
_G.screen1_on_post = nil
monarch.show(SCREEN1)
monarch.show(SCREEN2)
@ -528,7 +553,7 @@ return function()
local ok, err = monarch.post(SCREEN1, "foobar")
assert(not ok and err, "Expected monarch.post() to return false plus an error message")
cowait(0.1)
assert(not _G.screen1_foobar, "Screen1 should not have received a message")
assert(not _G.screen1_on_message, "Screen1 should not have received a message")
end)