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

Added support for multiple nodes per transition

This commit is contained in:
Björn Ritzl 2019-07-29 07:34:34 +02:00
parent 97c97e738d
commit f5879a5f63

View File

@ -104,73 +104,103 @@ function M.fade_in(node, from, easing, duration, delay, cb)
gui.animate(node, gui.PROP_COLOR, to, easing, duration, delay, cb) gui.animate(node, gui.PROP_COLOR, to, easing, duration, delay, cb)
end end
--- Create a transition for a node
-- @return Transition instance
function M.create(node)
assert(node, "You must provide a node")
--- Create a transition
-- @return Transition instance
local function create()
local instance = {} local instance = {}
local transitions = {} local transitions = {
[monarch.TRANSITION.SHOW_IN] = { urls = {}, transitions = {}, in_progress_count = 0, },
[monarch.TRANSITION.SHOW_OUT] = { urls = {}, transitions = {}, in_progress_count = 0, },
[monarch.TRANSITION.BACK_IN] = { urls = {}, transitions = {}, in_progress_count = 0, },
[monarch.TRANSITION.BACK_OUT] = { urls = {}, transitions = {}, in_progress_count = 0, },
}
local current_transition = nil local current_transition = nil
local initial_data = {} local function create_transition(transition_id, node, fn, easing, duration, delay)
initial_data.pos = gui.get_position(node) local t = transitions[transition_id]
initial_data.scale = gui.get_scale(node) t.transitions[#t.transitions + 1] = {
node = node,
local function create_transition(fn, easing, duration, delay) node_data = {
return { pos = gui.get_position(node),
scale = gui.get_scale(node),
},
fn = fn, fn = fn,
easing = easing, easing = easing,
duration = duration, duration = duration,
delay = delay, delay = delay,
in_progress = false, id = transition_id
urls = {},
id = nil
} }
end end
local function finish_transition(transition) local function finish_transition(transition_id)
transition.in_progress = false local t = transitions[transition_id]
local message = { transition = transition.id } if #t.urls > 0 then
while #transition.urls > 0 do local message = { transition = transition_id }
local url = table.remove(transition.urls) while #t.urls > 0 do
msg.post(url, monarch.TRANSITION.DONE, message) local url = table.remove(t.urls)
msg.post(url, monarch.TRANSITION.DONE, message)
end
end
current_transition = nil
end
local function check_and_finish_transition(transition_id)
local t = transitions[transition_id]
if t.in_progress_count == 0 then
finish_transition(transition_id)
end end
end end
local function start_transition(transition, transition_id, url) local function start_transition(transition_id, url)
table.insert(transition.urls, url) local t = transitions[transition_id]
if not transition.in_progress then table.insert(t.urls, url)
table.insert(transition.urls, msg.url()) if t.in_progress_count == 0 then
transition.in_progress = true table.insert(t.urls, msg.url())
transition.id = transition_id current_transition = t
current_transition = transition if #t.transitions > 0 then
transition.fn(node, initial_data, transition.easing, transition.duration, transition.delay or 0, function() for i=1,#t.transitions do
finish_transition(transition) local transition = t.transitions[i]
end) t.in_progress_count = t.in_progress_count + 1
transition.fn(transition.node, transition.node_data, transition.easing, transition.duration, transition.delay or 0, function()
t.in_progress_count = t.in_progress_count - 1
check_and_finish_transition(transition_id)
end)
end
else
check_and_finish_transition(transition_id)
end
end end
end end
-- Forward on_message calls here -- Forward on_message calls here
function instance.handle(message_id, message, sender) function instance.handle(message_id, message, sender)
if message_id == LAYOUT_CHANGED then if message_id == LAYOUT_CHANGED then
initial_data.pos = gui.get_position(node) for _,t in pairs(transitions) do
for _,transitions in pairs(t.transitions) do
transitions.node_data.pos = gui.get_position(transitions.node)
end
end
-- replay the current transition if the layout changes -- replay the current transition if the layout changes
-- this will ensure that things are still hidden if they -- this will ensure that things are still hidden if they
-- were transitioned out -- were transitioned out
if current_transition then if current_transition then
current_transition.fn(node, initial_data, current_transition.easing, 0, 0) for _,transition in pairs(current_transition.transitions) do
if current_transition.in_progress then local node = transition.node
finish_transition(current_transition) transition.fn(transition.node, transition.node_data, transition.easing, 0, 0)
end
if current_transition.in_progress_count > 0 then
finish_transition(message_id)
end end
end end
else elseif message_id == monarch.TRANSITION.SHOW_IN
local transition = transitions[message_id] or message_id == monarch.TRANSITION.SHOW_OUT
if transition then or message_id == monarch.TRANSITION.BACK_IN
start_transition(transition, message_id, sender) or message_id == monarch.TRANSITION.BACK_OUT then
end start_transition(message_id, sender)
end end
end end
@ -180,38 +210,57 @@ function M.create(node)
-- @param easing Easing function to use -- @param easing Easing function to use
-- @param duration Transition duration -- @param duration Transition duration
-- @param delay Transition delay -- @param delay Transition delay
function instance.show_in(fn, easing, duration, delay) function instance.show_in(node, fn, easing, duration, delay)
transitions[monarch.TRANSITION.SHOW_IN] = create_transition(fn, easing, duration, delay) create_transition(monarch.TRANSITION.SHOW_IN, node, fn, easing, duration, delay)
return instance return instance
end end
-- Specify the transition function when this node is transitioned -- Specify the transition function when this node is transitioned
-- from when showing another screen -- from when showing another screen
function instance.show_out(fn, easing, duration, delay) function instance.show_out(node, fn, easing, duration, delay)
transitions[monarch.TRANSITION.SHOW_OUT] = create_transition(fn, easing, duration, delay) create_transition(monarch.TRANSITION.SHOW_OUT, node, fn, easing, duration, delay)
return instance return instance
end end
--- Specify the transition function when this node is transitioned --- Specify the transition function when this node is transitioned
-- to when navigating back in the screen stack -- to when navigating back in the screen stack
function instance.back_in(fn, easing, duration, delay) function instance.back_in(node, fn, easing, duration, delay)
transitions[monarch.TRANSITION.BACK_IN] = create_transition(fn, easing, duration, delay) create_transition(monarch.TRANSITION.BACK_IN, node, fn, easing, duration, delay)
return instance return instance
end end
--- Specify the transition function when this node is transitioned --- Specify the transition function when this node is transitioned
-- from when navigating back in the screen stack -- from when navigating back in the screen stack
function instance.back_out(fn, easing, duration, delay) function instance.back_out(node, fn, easing, duration, delay)
transitions[monarch.TRANSITION.BACK_OUT] = create_transition(fn, easing, duration, delay) create_transition(monarch.TRANSITION.BACK_OUT, node, fn, easing, duration, delay)
return instance return instance
end end
-- set default transitions (instant) return instance
instance.show_in(M.instant) end
instance.show_out(M.instant)
instance.back_in(M.instant)
instance.back_out(M.instant)
function M.create(node)
local instance = create()
-- backward compatibility with the old version of create
-- where a single node was used
if node then
local show_in = instance.show_in
local show_out = instance.show_out
local back_in = instance.back_in
local back_out = instance.back_out
instance.show_in = function(fn, easing, duration, delay)
return show_in(node, fn, easing, duration, delay)
end
instance.show_out = function(fn, easing, duration, delay)
return show_out(node, fn, easing, duration, delay)
end
instance.back_in = function(fn, easing, duration, delay)
return back_in(node, fn, easing, duration, delay)
end
instance.back_out = function(fn, easing, duration, delay)
return back_out(node, fn, easing, duration, delay)
end
end
return instance return instance
end end