From 1314b4363391d06b2221a1b6f8b4c9a996ff83a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bjo=CC=88rn=20Ritzl?= Date: Mon, 28 Jun 2021 01:04:23 +0200 Subject: [PATCH] monarch.back_to() test --- example/basic/basic.collection | 58 ++++++++ example/basic/screen2.gui | 121 ++++++++++++++- example/basic/screen2.gui_script | 4 +- example/basic/screen3.collection | 37 +++++ example/basic/screen3.gui | 248 +++++++++++++++++++++++++++++++ example/basic/screen3.gui_script | 15 ++ game.project | 2 +- monarch/monarch.lua | 109 +++++++++----- 8 files changed, 553 insertions(+), 41 deletions(-) create mode 100644 example/basic/screen3.collection create mode 100644 example/basic/screen3.gui create mode 100644 example/basic/screen3.gui_script diff --git a/example/basic/basic.collection b/example/basic/basic.collection index 467ee23..1612c9d 100644 --- a/example/basic/basic.collection +++ b/example/basic/basic.collection @@ -151,3 +151,61 @@ embedded_instances { z: 1.0 } } +embedded_instances { + id: "screen3" + 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: \"screen3\"\n" + " type: PROPERTY_TYPE_HASH\n" + " }\n" + "}\n" + "embedded_components {\n" + " id: \"collectionproxy\"\n" + " type: \"collectionproxy\"\n" + " data: \"collection: \\\"/example/basic/screen3.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 + } +} diff --git a/example/basic/screen2.gui b/example/basic/screen2.gui index e603d00..deb2705 100644 --- a/example/basic/screen2.gui +++ b/example/basic/screen2.gui @@ -11,7 +11,124 @@ background_color { } nodes { position { - x: 320.0 + x: 519.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: 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: "showscreen3" + 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 +} +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 3" + 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: "showscreen3" + 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 +} +nodes { + position { + x: 132.0 y: 568.0 z: 0.0 w: 1.0 @@ -98,7 +215,7 @@ nodes { blend_mode: BLEND_MODE_ALPHA text: "BACK" font: "example" - id: "text" + id: "text1" xanchor: XANCHOR_NONE yanchor: YANCHOR_NONE pivot: PIVOT_CENTER diff --git a/example/basic/screen2.gui_script b/example/basic/screen2.gui_script index 98c49bc..95e3527 100644 --- a/example/basic/screen2.gui_script +++ b/example/basic/screen2.gui_script @@ -6,7 +6,9 @@ end 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 + if gui.pick_node(gui.get_node("showscreen3"), action.x, action.y) then + monarch.show(hash("screen3")) + elseif gui.pick_node(gui.get_node("backbutton"), action.x, action.y) then monarch.back() end end diff --git a/example/basic/screen3.collection b/example/basic/screen3.collection new file mode 100644 index 0000000..a95488c --- /dev/null +++ b/example/basic/screen3.collection @@ -0,0 +1,37 @@ +name: "screen3" +scale_along_z: 0 +embedded_instances { + id: "go" + data: "components {\n" + " id: \"screen3\"\n" + " component: \"/example/basic/screen3.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" + "}\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 + } +} diff --git a/example/basic/screen3.gui b/example/basic/screen3.gui new file mode 100644 index 0000000..c30613b --- /dev/null +++ b/example/basic/screen3.gui @@ -0,0 +1,248 @@ +script: "/example/basic/screen3.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: 137.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: 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: "backbutton" + 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 +} +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: "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: "backbutton" + 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 +} +nodes { + position { + x: 525.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: 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: "tostart" + 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 +} +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: "TOSTART" + font: "example" + id: "text1" + 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: "tostart" + 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 +} +material: "/builtins/materials/gui.material" +adjust_reference: ADJUST_REFERENCE_PARENT +max_nodes: 512 diff --git a/example/basic/screen3.gui_script b/example/basic/screen3.gui_script new file mode 100644 index 0000000..c4c4fa9 --- /dev/null +++ b/example/basic/screen3.gui_script @@ -0,0 +1,15 @@ +local monarch = require "monarch.monarch" + +function init(self) + msg.post(".", "acquire_input_focus") +end + +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("tostart"), action.x, action.y) then + monarch.back_to(hash("screen1")) + end + end +end \ No newline at end of file diff --git a/game.project b/game.project index 4bd4ca5..cc66101 100644 --- a/game.project +++ b/game.project @@ -1,7 +1,7 @@ [project] title = Monarch version = 0.9 -dependencies = https://github.com/britzl/deftest/archive/2.7.0.zip +dependencies#0 = https://github.com/britzl/deftest/archive/2.7.0.zip [bootstrap] main_collection = /example/advanced/advanced.collectionc diff --git a/monarch/monarch.lua b/monarch/monarch.lua index 563d5b9..3ce9a3a 100644 --- a/monarch/monarch.lua +++ b/monarch/monarch.lua @@ -869,51 +869,86 @@ function M.hide(id, cb) end +local function internal_back(to, data, cb) + if #stack == 0 then + cb() + return + end + + if not to then + if #stack > 1 then + to = stack[#stack - 1] + end + end + + queue_action(function(action_done) + local co + co = coroutine.create(function() + local callbacks = callback_tracker() + if not to then + back_out(table.remove(stack), nil, WAIT_FOR_TRANSITION, callbacks.track()) + else + if data then + to.data = data + end + + -- close visible screens until target screen is below top screen + while to ~= stack[#stack - 1] do + local top = table.remove(stack) + local below = stack[#stack] + if top.visible then + back_out(top, below, WAIT_FOR_TRANSITION, callbacks.track()) + callbacks.yield_until_done() + end + end + + local top = table.remove(stack) + if to == top then + -- 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 + back_out(to, to, WAIT_FOR_TRANSITION, function() + back_in(to, to, WAIT_FOR_TRANSITION, callbacks.track()) + end) + else + back_in(to, top, DO_NOT_WAIT_FOR_TRANSITION, function() + if top.visible then + back_out(top, to, WAIT_FOR_TRANSITION, callbacks.track()) + end + end) + end + end + + callbacks.when_done(function() + pcallfn(cb) + pcallfn(action_done) + end) + end) + assert(coroutine.resume(co)) + end) +end + -- Go back to the previous screen in the stack. -- @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) log("back() queuing action") - - queue_action(function(action_done) - local callbacks = callback_tracker() - 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 - back_out(screen, top, WAIT_FOR_TRANSITION, function() - if data then - top.data = data - end - back_in(top, screen, WAIT_FOR_TRANSITION, callbacks.track()) - end) - else - if top then - if data then - top.data = data - end - back_in(top, screen, DO_NOT_WAIT_FOR_TRANSITION, function() - back_out(screen, top, WAIT_FOR_TRANSITION, callbacks.track()) - end) - else - back_out(screen, top, WAIT_FOR_TRANSITION, callbacks.track()) - end - end - end - - callbacks.when_done(function() - pcallfn(cb) - pcallfn(action_done) - end) - end) - - return true -- return true for legacy reasons (before queue existed) + internal_back(nil, data, cb) end +-- Go back to the previous screen in the stack. +-- @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_to(id, data, cb) + log("back_to() queuing action") + id = tohash(id) + assert(screens[id], ("There is no screen registered with id %s"):format(tostring(id))) + local screen = screens[id] + internal_back(screen, data, cb) +end + + + --- Check if a screen is preloading via monarch.preload() or automatically -- via the Preload screen option -- @param id Screen id