diff --git a/README.md b/README.md index 6edc43e..eef1233 100644 --- a/README.md +++ b/README.md @@ -166,6 +166,21 @@ You can create and use your own transition as long as the provided transition fu * ```delay``` (number) - Transition delay in seconds. * ```cb``` (function) - This function must be called when the transition is completed. +### Dynamic orientation and resized windows +When using dynamic screen orientation together with gui layouts or using transitions on a platform where the window can be resized it's important to make sure that the created transitions adapt to the change in orientation or window size. The transition system takes care of layout changes automatically, but when it comes to changes in window size you need to notify the transition manually: + + local transitions = require "monarch.transitions.gui" + + function init(self) + self.transition = transitions.create(gui.get_node("root")) + 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) + end + end + ## Screen focus gain/loss Monarch will send focus gain and focus loss messages if a Focus Url 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: diff --git a/example/example.display_profiles b/example/example.display_profiles new file mode 100644 index 0000000..e913544 --- /dev/null +++ b/example/example.display_profiles @@ -0,0 +1,14 @@ +profiles { + name: "Landscape" + qualifiers { + width: 1136 + height: 640 + } +} +profiles { + name: "Portrait" + qualifiers { + width: 640 + height: 1136 + } +} diff --git a/example/menu.gui b/example/menu.gui index 8b281fa..62c931c 100644 --- a/example/menu.gui +++ b/example/menu.gui @@ -481,5 +481,243 @@ nodes { text_tracking: 0.0 } material: "/builtins/materials/gui.material" +layouts { + name: "Landscape" + nodes { + position { + x: 568.0 + y: 320.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: "startgame_button" + 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 + overridden_fields: 1 + template_node_child: false + size_mode: SIZE_MODE_MANUAL + } + nodes { + position { + x: 977.0 + y: 570.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: "about_button" + 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 + overridden_fields: 1 + template_node_child: false + size_mode: SIZE_MODE_MANUAL + } + nodes { + position { + x: 150.0 + y: 570.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: "back_button" + 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 + overridden_fields: 1 + template_node_child: false + size_mode: SIZE_MODE_MANUAL + } + nodes { + position { + x: 568.0 + y: 570.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_TEXT + blend_mode: BLEND_MODE_ALPHA + text: "" + font: "example" + id: "timestamp" + 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 + overridden_fields: 1 + template_node_child: false + text_leading: 1.0 + text_tracking: 0.0 + } +} +layouts { + name: "Portrait" +} adjust_reference: ADJUST_REFERENCE_PARENT max_nodes: 512 diff --git a/game.project b/game.project index 4b5505e..2ba9b3a 100644 --- a/game.project +++ b/game.project @@ -4,7 +4,7 @@ version = 0.9 dependencies = https://github.com/britzl/deftest/archive/1.2.1.zip [bootstrap] -main_collection = /test/test.collectionc +main_collection = /example/example.collectionc [input] game_binding = /input/game.input_bindingc @@ -12,6 +12,8 @@ game_binding = /input/game.input_bindingc [display] width = 640 height = 1136 +dynamic_orientation = 1 +display_profiles = /example/example.display_profilesc [script] shared_state = 1 diff --git a/monarch/transitions/gui.lua b/monarch/transitions/gui.lua index 1e321e7..3b279e5 100644 --- a/monarch/transitions/gui.lua +++ b/monarch/transitions/gui.lua @@ -2,16 +2,32 @@ local monarch = require "monarch.monarch" 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) +local WIDTH = nil +local HEIGHT = nil +local LEFT = nil +local RIGHT = nil +local TOP = nil +local BOTTOM = nil local ZERO_SCALE = vmath.vector3(0, 0, 1) +local LAYOUT_CHANGED = hash("layout_changed") + +-- Notify the transition system that the window size has changed +-- @param width +-- @param height +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) +end + +M.window_resized(tonumber(sys.get_config("display.width")), tonumber(sys.get_config("display.height"))) + + function M.instant(node, to, easing, duration, delay, cb) cb() end @@ -111,9 +127,13 @@ function M.create(node) -- Forward on_message calls here function instance.handle(message_id, message, sender) - local transition = transitions[message_id] - if transition then - start_transition(transition, sender) + if message_id == LAYOUT_CHANGED then + initial_data.pos = gui.get_position(node) + else + local transition = transitions[message_id] + if transition then + start_transition(transition, sender) + end end end