Gui.set_screen_position() and gui.screen_pos_to_node_pos()

#1

This is implementation of gui.set_screen_position() and gui.screen_pos_to_node_pos() functions for Defold. This library will be useful if you want to get screen position of the node and set this position for another node with the different parent of even in another component.

Installation

You can use this library in your own project by adding this project as a Defold library dependency. Open your game.project file and in the dependencies field under project add:

https://github.com/AGulev/set_screen_position/archive/master.zip

First of all, we need to recalculate all coefficient when you change screen size, that why we need to add a few lines into render_script:

-- require the module
local gui_extra_functions = require "gui_extra_functions.gui_extra_functions"
...
function init(self)
  ...
  -- calculate coefficients when init the game
  gui_extra_functions.update_coef(render.get_window_width(), render.get_window_height())
end
...

function on_message(self, message_id, message)
  ...
  -- calculate coefficients when changing screen size
elseif message_id == hash("window_resized") then
  gui_extra_functions.update_coef(render.get_window_width(), render.get_window_height())
elseif
...
end

Without Layouts

If you don’t use layouts, then just call init() method in any gui_script:

-- any gui_script file
local gui_extra_functions = require "gui_extra_functions.gui_extra_functions"
...
function init(self)
  ...
  gui_extra_functions.init()
end

With Layouts

We need to call init() method in any gui_script with all possible options for layouts:

-- any gui_script file
local gui_extra_functions = require "gui_extra_functions.gui_extra_functions"
...
function init(self)
  ...
  -- table with layouts should have next format:
  -- {[hashed_layout_id] = {width = layout_width, height = layout_height} }
  gui_extra_functions.init({
    [hash("Standard")] = {
      width = 960,
      height = 640
    },
    [hash("Portrait")] = {
      width = 720,
      height = 1280
    },
    [hash("Landscape")] = {
      width = 1280,
      height = 720
    },
  })
end

Usage

-- get screen position of the node
local screen_pos = gui.get_screen_position(some_node_with_difficult_hierarchy)

-- set screen position for another node
gui.set_screen_position(some_other_node, screen_pos)

-- or convert screen position to position relative to this node,
-- for example,  for gui.animate()
local local_node_pos = gui.screen_pos_to_node_pos(screen_pos, some_other_node)
gui.animate(animation_node, gui.PROP_POSITION, local_node_pos, gui.EASING_LINEAR, 1)

Thanks, @ross.grams for his functions for different adjust modes and @britzl for help with gui.set_parent() logic (magic).

7 Likes

Gui.get_screen_position() returns the wrong position if called after init() (SOLVED)
Gui.get_screen_position() returns the wrong position if called after init() (SOLVED)
Bug in dx/dy for multi touch on Android (DEF-1726)(SOLVEDx3)
Bug in dx/dy for multi touch on Android (DEF-1726)(SOLVEDx3)