Get actual screen bounds in a GUI

I’ve always found it tricky to position gui nodes after the window has been resized. For example, how do I position a text node exactly outside the visible screen area, so the reveal animation shows consistently on various screen sizes?

Well, here is a hack nifty function that can help with that!

    local function get_gui_bounds()

    	local NODE_SIZE = vmath.vector3(100)
    	
    	local display_width = sys.get_config_int("display.width")
    	local display_height = sys.get_config_int("display.height")

    	-- Node anchored top left
    	local top_left_position = vmath.vector3(0, display_height, 0)
    	local top_left_node = gui.new_box_node(top_left_position, NODE_SIZE)
    	gui.set_xanchor(top_left_node, gui.ANCHOR_LEFT)
    	gui.set_yanchor(top_left_node, gui.ANCHOR_TOP)

    	-- Node anchored bottom right
    	local bottom_right_position = vmath.vector3(display_width, 0, 0)
    	local bottom_right_node = gui.new_box_node(bottom_right_position, NODE_SIZE)
    	gui.set_xanchor(bottom_right_node, gui.ANCHOR_RIGHT)
    	gui.set_yanchor(bottom_right_node, gui.ANCHOR_BOTTOM)

    	-- Get actual top left position
    	local top_left_probe_node = gui.new_box_node(vmath.vector3(), NODE_SIZE)
    	gui.set_color(top_left_probe_node, vmath.vector3(1,0,0))
    	gui.set_parent(top_left_probe_node, top_left_node, false)
    	gui.set_parent(top_left_probe_node, nil, true) -- This can only happen once per frame
    	local actual_top_left_position = gui.get_position(top_left_probe_node)

    	-- Get actual bottom right position
    	local bottom_right_probe_node = gui.new_box_node(vmath.vector3(), NODE_SIZE)
    	gui.set_color(bottom_right_probe_node, vmath.vector3(0,1,0))
    	gui.set_parent(bottom_right_probe_node, bottom_right_node, false)
    	gui.set_parent(bottom_right_probe_node, nil, true) -- This can only happen once per frame
    	local actual_bottom_right_position = gui.get_position(bottom_right_probe_node)

    	gui.delete_node(top_left_node)
    	gui.delete_node(bottom_right_node)
    	gui.delete_node(top_left_probe_node)
    	gui.delete_node(bottom_right_probe_node)

    	local actual_screen_bounds = vmath.vector4(actual_top_left_position.x, actual_top_left_position.y, actual_bottom_right_position.x, actual_bottom_right_position.y)

    	return actual_screen_bounds



    end

If there is a cleaner way of achieving this, I’d be very keen to hear about it. :sweat_smile:

11 Likes