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

Improved examples. Added transitions

This commit is contained in:
Björn Ritzl 2017-09-04 21:26:06 +02:00
parent 1e4b7ea60f
commit a68fac766f
14 changed files with 416 additions and 90 deletions

View File

@ -73,32 +73,21 @@ You can add optional transitions when navigating between screens. The default be
* ````transition_back_in```` * ````transition_back_in````
* ````transition_back_out```` * ````transition_back_out````
When a transition is completed it is up to the developer to send a ````transition_done```` message back to the sender to indicate that the transition is completed and that Monarch can continue the navigation sequence. Example: When a transition is completed it is up to the developer to send a ````transition_done```` message back to the sender to indicate that the transition is completed and that Monarch can continue the navigation sequence. Monarch comes with a system for setting up transitions easily in a gui.script. Example:
local transitions = require "monarch.transitions.gui"
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"))
.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)
end
function on_message(self, message_id, message, sender) function on_message(self, message_id, message, sender)
if message_id == hash("transition_show_in") then self.transition.handle(message_id, message, sender)
-- slide in from the right
gui.set_position(self.root, self.initial_position + vmath.vector3(1000, 0, 0))
gui.animate(self.root, gui.PROP_POSITION, self.initial_position, go.EASING_INOUTQUAD, 0.6, 0, function()
msg.post(sender, "transition_done")
end)
elseif message_id == hash("transition_show_out") then
-- slide out to the left
gui.animate(self.root, gui.PROP_POSITION, self.initial_position - vmath.vector3(1000, 0, 0), go.EASING_INOUTQUAD, 0.6, 0, function()
msg.post(sender, "transition_done")
end)
end
elseif message_id == hash("transition_back_in") then
-- slide in from the left
gui.set_position(self.root, self.initial_position - vmath.vector3(1000, 0, 0))
gui.animate(self.root, gui.PROP_POSITION, self.initial_position, go.EASING_INOUTQUAD, 0.6, 0, function()
msg.post(sender, "transition_done")
end)
end
elseif message_id == hash("transition_back_out") then
-- slide out to the right
gui.animate(self.root, gui.PROP_POSITION, self.initial_position + vmath.vector3(1000, 0, 0), go.EASING_INOUTQUAD, 0.6, 0, function()
msg.post(sender, "transition_done")
end)
end
end end

View File

@ -9,6 +9,60 @@ background_color {
z: 0.0 z: 0.0
w: 0.0 w: 0.0
} }
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: 0.0
y: 0.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: "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
}
nodes { nodes {
position { position {
x: 320.0 x: 320.0
@ -48,6 +102,7 @@ nodes {
yanchor: YANCHOR_NONE yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: "" layer: ""
inherit_alpha: true inherit_alpha: true
slice9 { slice9 {

View File

@ -1,7 +1,14 @@
local monarch = require "monarch.monarch" local monarch = require "monarch.monarch"
local transitions = require "monarch.transitions.gui"
function init(self) function init(self)
msg.post(".", "acquire_input_focus") msg.post(".", "acquire_input_focus")
self.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)
end end
function on_input(self, action_id, action) function on_input(self, action_id, action)
@ -12,7 +19,6 @@ function on_input(self, action_id, action)
end end
end end
function on_reload(self) function on_message(self, message_id, message, sender)
-- Add input-handling code here self.transition.handle(message_id, message, sender)
-- Remove this function if not needed
end end

View File

@ -21,6 +21,26 @@ embedded_instances {
" value: \"menu\"\n" " value: \"menu\"\n"
" type: PROPERTY_TYPE_HASH\n" " type: PROPERTY_TYPE_HASH\n"
" }\n" " }\n"
" properties {\n"
" id: \"transition_show_in\"\n"
" value: \"menu:/go#menu\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
" properties {\n"
" id: \"transition_show_out\"\n"
" value: \"menu:/go#menu\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
" properties {\n"
" id: \"transition_back_in\"\n"
" value: \"menu:/go#menu\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
" properties {\n"
" id: \"transition_back_out\"\n"
" value: \"menu:/go#menu\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
"}\n" "}\n"
"embedded_components {\n" "embedded_components {\n"
" id: \"collectionproxy\"\n" " id: \"collectionproxy\"\n"
@ -207,6 +227,26 @@ embedded_instances {
" value: \"game\"\n" " value: \"game\"\n"
" type: PROPERTY_TYPE_HASH\n" " type: PROPERTY_TYPE_HASH\n"
" }\n" " }\n"
" properties {\n"
" id: \"transition_show_in\"\n"
" value: \"game:/go#game\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
" properties {\n"
" id: \"transition_show_out\"\n"
" value: \"game:/go#game\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
" properties {\n"
" id: \"transition_back_in\"\n"
" value: \"game:/go#game\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
" properties {\n"
" id: \"transition_back_out\"\n"
" value: \"game:/go#game\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
"}\n" "}\n"
"embedded_components {\n" "embedded_components {\n"
" id: \"collectionproxy\"\n" " id: \"collectionproxy\"\n"
@ -270,6 +310,26 @@ embedded_instances {
" value: \"true\"\n" " value: \"true\"\n"
" type: PROPERTY_TYPE_BOOLEAN\n" " type: PROPERTY_TYPE_BOOLEAN\n"
" }\n" " }\n"
" properties {\n"
" id: \"transition_show_in\"\n"
" value: \"popup:/go#popup\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
" properties {\n"
" id: \"transition_show_out\"\n"
" value: \"popup:/go#popup\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
" properties {\n"
" id: \"transition_back_in\"\n"
" value: \"popup:/go#popup\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
" properties {\n"
" id: \"transition_back_out\"\n"
" value: \"popup:/go#popup\"\n"
" type: PROPERTY_TYPE_URL\n"
" }\n"
"}\n" "}\n"
"embedded_components {\n" "embedded_components {\n"
" id: \"collectionproxy\"\n" " id: \"collectionproxy\"\n"

View File

@ -2,4 +2,5 @@ local monarch = require "monarch.monarch"
function init(self) function init(self)
monarch.show(hash("menu")) monarch.show(hash("menu"))
msg.post("@render:/", "clear_color", { color = vmath.vector4(0.4, 0.6, 0.8,1.0) })
end end

View File

@ -9,6 +9,60 @@ background_color {
z: 0.0 z: 0.0
w: 0.0 w: 0.0
} }
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: 0.0
y: 0.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: "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
}
nodes { nodes {
position { position {
x: 320.0 x: 320.0
@ -48,6 +102,7 @@ nodes {
yanchor: YANCHOR_NONE yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: "" layer: ""
inherit_alpha: true inherit_alpha: true
slice9 { slice9 {

View File

@ -1,19 +1,24 @@
local monarch = require "monarch.monarch" local monarch = require "monarch.monarch"
local transitions = require "monarch.transitions.gui"
function init(self) function init(self)
msg.post(".", "acquire_input_focus") msg.post(".", "acquire_input_focus")
self.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)
end end
function on_input(self, action_id, action) function on_input(self, action_id, action)
if action_id == hash("touch") and action.released then if action_id == hash("touch") and action.released then
if gui.pick_node(gui.get_node("startgame_button"), action.x, action.y) then if gui.pick_node(gui.get_node("startgame_button"), action.x, action.y) then
print("BUTTON***************************************")
monarch.show(hash("popup")) monarch.show(hash("popup"))
end end
end end
end end
function on_reload(self) function on_message(self, message_id, message, sender)
-- Add input-handling code here self.transition.handle(message_id, message, sender)
-- Remove this function if not needed
end end

View File

@ -1,10 +1,17 @@
local monarch = require "monarch.monarch" local monarch = require "monarch.monarch"
local transitions = require "monarch.transitions.gui"
function init(self) function init(self)
msg.post(".", "acquire_input_focus") msg.post(".", "acquire_input_focus")
self.ok = gui.get_node("ok_button") self.ok = gui.get_node("ok_button")
self.cancel = gui.get_node("cancel_button") self.cancel = gui.get_node("cancel_button")
gui.set_render_order(16) gui.set_render_order(16)
self.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)
end end
function on_input(self, action_id, action) function on_input(self, action_id, action)
@ -18,3 +25,7 @@ function on_input(self, action_id, action)
end end
end end
end end
function on_message(self, message_id, message, sender)
self.transition.handle(message_id, message, sender)
end

View File

@ -9,6 +9,60 @@ background_color {
z: 0.0 z: 0.0
w: 0.0 w: 0.0
} }
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: 0.0
y: 0.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: "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
}
nodes { nodes {
position { position {
x: 320.0 x: 320.0
@ -48,6 +102,7 @@ nodes {
yanchor: YANCHOR_NONE yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: "" layer: ""
inherit_alpha: true inherit_alpha: true
slice9 { slice9 {
@ -165,6 +220,7 @@ nodes {
yanchor: YANCHOR_NONE yanchor: YANCHOR_NONE
pivot: PIVOT_CENTER pivot: PIVOT_CENTER
adjust_mode: ADJUST_MODE_FIT adjust_mode: ADJUST_MODE_FIT
parent: "root"
layer: "" layer: ""
inherit_alpha: true inherit_alpha: true
slice9 { slice9 {

View File

@ -1,13 +1,16 @@
local monarch = require "monarch.monarch" local monarch = require "monarch.monarch"
local transitions = require "monarch.transitions.gui"
function init(self) function init(self)
msg.post(".", "acquire_input_focus") msg.post(".", "acquire_input_focus")
self.play = gui.get_node("play_button") self.play = gui.get_node("play_button")
self.back = gui.get_node("back_button") self.back = gui.get_node("back_button")
self.play_position = gui.get_position(self.play)
self.back_position = gui.get_position(self.back) self.transition = transitions.create(gui.get_node("root"))
gui.set_position(self.back, self.back_position + vmath.vector3(0, 1000, 0)) .show_in(transitions.slide_in_right, gui.EASING_OUTQUAD, 0.6, 0)
gui.set_position(self.play, self.play_position + vmath.vector3(0, 1000, 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)
end end
function on_input(self, action_id, action) function on_input(self, action_id, action)
@ -23,15 +26,5 @@ function on_input(self, action_id, action)
end end
function on_message(self, message_id, message, sender) function on_message(self, message_id, message, sender)
if message_id == hash("transition_show_in") or message_id == hash("transition_back_in") then self.transition.handle(message_id, message, sender)
gui.animate(self.play, gui.PROP_POSITION, self.play_position, go.EASING_INQUAD, 0.6, 0, function()
msg.post(sender, "transition_done")
end)
gui.animate(self.back, gui.PROP_POSITION, self.back_position, go.EASING_INQUAD, 0.6)
elseif message_id == hash("transition_show_out") or message_id == hash("transition_back_out") then
gui.animate(self.play, gui.PROP_POSITION, self.play_position + vmath.vector3(0, 1000, 0), go.EASING_INQUAD, 0.6, 0, function()
msg.post(sender, "transition_done")
end)
gui.animate(self.back, gui.PROP_POSITION, self.back_position + vmath.vector3(0, 1000, 0), go.EASING_INQUAD, 0.6)
end
end end

View File

@ -100,6 +100,7 @@ local function back_out(screen)
local co local co
co = coroutine.create(function() co = coroutine.create(function()
screen.co = co screen.co = co
msg.post(screen.script, "release_input_focus")
msg.post(screen.script, "monarch_context") msg.post(screen.script, "monarch_context")
coroutine.yield() coroutine.yield()
msg.post(screen.transitions.back_out, "transition_back_out") msg.post(screen.transitions.back_out, "transition_back_out")

View File

@ -1,32 +0,0 @@
local monarch = require "monarch.monarch"
function init(self)
-- Add initialization code here
-- Remove this function if not needed
end
function final(self)
-- Add finalization code here
-- Remove this function if not needed
end
function update(self, dt)
-- Add update code here
-- Remove this function if not needed
end
function on_message(self, message_id, message, sender)
-- Add message-handling code here
-- Remove this function if not needed
end
function on_input(self, action_id, action)
-- Add input-handling code here
-- Remove this function if not needed
end
function on_reload(self)
-- Add reload-handling code here
-- Remove this function if not needed
end

View File

@ -10,7 +10,6 @@ go.property("transition_back_out", msg.url())
function init(self) function init(self)
print("screen init", self.proxy)
monarch.register(self.screen_id, self.screen_proxy, self.popup, { monarch.register(self.screen_id, self.screen_proxy, self.popup, {
show_in = self.transition_show_in, show_in = self.transition_show_in,
show_out = self.transition_show_out, show_out = self.transition_show_out,
@ -20,25 +19,20 @@ function init(self)
end end
function final(self) function final(self)
print("screen final", self.proxy)
monarch.unregister(self.screen_id) monarch.unregister(self.screen_id)
end end
function on_message(self, message_id, message, sender) function on_message(self, message_id, message, sender)
print("screen on_message", message_id, sender)
if message_id == hash("show") then if message_id == hash("show") then
monarch.show(self.screen_id, message.clear) monarch.show(self.screen_id, message.clear)
elseif message_id == hash("hide") then elseif message_id == hash("hide") then
monarch.hide(self.screen_id) monarch.hide(self.screen_id)
elseif message_id == hash("back") then elseif message_id == hash("back") then
monarch.hide(self.screen_id) monarch.hide(self.screen_id)
elseif message_id == hash("transition_show_in") then elseif message_id == hash("transition_show_in")
msg.post(sender, "transition_done") or message_id == hash("transition_show_out")
elseif message_id == hash("transition_show_out") then or message_id == hash("transition_back_in")
msg.post(sender, "transition_done") or message_id == hash("transition_back_out") then
elseif message_id == hash("transition_back_in") then
msg.post(sender, "transition_done")
elseif message_id == hash("transition_back_out") then
msg.post(sender, "transition_done") msg.post(sender, "transition_done")
else else
monarch.on_message(message_id, message, sender) monarch.on_message(message_id, message, sender)

132
monarch/transitions/gui.lua Normal file
View File

@ -0,0 +1,132 @@
local M = {}
local WIDTH = tonumber(sys.get_config("display.width"))
local HEIGHT = tonumber(sys.get_config("display.height"))
local LEFT = vmath.vector3(-WIDTH * 2, 0, 0)
local RIGHT = vmath.vector3(WIDTH * 2, 0, 0)
local TOP = vmath.vector3(0, HEIGHT * 2, 0)
local BOTTOM = vmath.vector3(0, -HEIGHT * 2, 0)
function M.instant(node, to, easing, duration, delay, url)
msg.post(url, "transition_done")
end
local function slide_in(direction, node, to, easing, duration, delay, url)
local from = to + direction
gui.set_position(node, from)
gui.animate(node, gui.PROP_POSITION, to, easing, duration, delay, function()
msg.post(url, "transition_done")
end)
end
function M.slide_in_left(node, to, easing, duration, delay, url)
return slide_in(LEFT, node, to, easing, duration, delay, url)
end
function M.slide_in_right(node, to, easing, duration, delay, url)
slide_in(RIGHT, node, to, easing, duration, delay, url)
end
function M.slide_in_top(node, to, easing, duration, delay, url)
slide_in(TOP, node, to, easing, duration, delay, url)
end
function M.slide_in_bottom(node, to, easing, duration, delay, url)
slide_in(BOTTOM, node, to, easing, duration, delay, url)
end
local function slide_out(direction, node, from, easing, duration, delay, url)
local to = from + direction
gui.set_position(node, from)
gui.animate(node, gui.PROP_POSITION, to, easing, duration, delay, function()
msg.post(url, "transition_done")
end)
end
function M.slide_out_left(node, from, easing, duration, delay, url)
slide_out(LEFT, node, from, easing, duration, delay, url)
end
function M.slide_out_right(node, from, easing, duration, delay, url)
slide_out(RIGHT, node, from, easing, duration, delay, url)
end
function M.slide_out_top(node, from, easing, duration, delay, url)
slide_out(TOP, node, from, easing, duration, delay, url)
end
function M.slide_out_bottom(node, from, easing, duration, delay, url)
slide_out(BOTTOM, node, from, easing, duration, delay, url)
end
--- Create a transition for a node
-- @return Transition instance
function M.create(node)
assert(node, "You must provide a node")
local instance = {}
local transitions = {
[hash("transition_show_in")] = M.instant,
[hash("transition_show_out")] = M.instant,
[hash("transition_back_in")] = M.instant,
[hash("transition_back_out")] = M.instant,
}
local initial_position = gui.get_position(node)
-- Forward on_message calls here
function instance.handle(message_id, message, sender)
transitions[message_id](sender)
end
-- Specify the transition function when this node is transitioned
-- to
-- @param fn Transition function (see slide_in_left and other above)
-- @param easing Easing function to use
-- @param duration Transition duration
-- @param delay Transition delay
function instance.show_in(fn, easing, duration, delay)
transitions[hash("transition_show_in")] = function(url)
print("transition_show_in", url, fn)
fn(node, initial_position, easing, duration, delay, url)
end
return instance
end
-- Specify the transition function when this node is transitioned
-- from when showing another screen
function instance.show_out(fn, easing, duration, delay)
transitions[hash("transition_show_out")] = function(url)
print("transition_show_out")
fn(node, initial_position, easing, duration, delay, url)
end
return instance
end
--- Specify the transition function when this node is transitioned
-- to when navigating back in the screen stack
function instance.back_in(fn, easing, duration, delay)
transitions[hash("transition_back_in")] = function(url)
print("transition_back_in")
fn(node, initial_position, easing, duration, delay, url)
end
return instance
end
--- Specify the transition function when this node is transitioned
-- from when navigating back in the screen stack
function instance.back_out(fn, easing, duration, delay)
transitions[hash("transition_back_out")] = function(url)
print("transition_back_out")
fn(node, initial_position, easing, duration, delay, url)
end
return instance
end
return instance
end
return M