Oculus VR template: /s3d_ui.lua — code sample - Stingray Lua API Reference

Oculus VR template: /s3d_ui.lua — code sample

Code

--[[
    Basic code for rendering a HUD overlay and getting menu input
    Uses the Stingray3D interface. 
]]

require 'core/appkit/lua/class'

Project.S3DUI = Appkit.class(Project.S3DUI)
local UI = Project.S3DUI

local font = 'core/performance_hud/debug'
local font_material = 'debug'

function UI:init(gui)
    self.gui = gui
    self.current_menu_item = 1
end

local function draw_text(gui, text, size, at, color)
    stingray.Gui.text(gui, text, font, size, font_material, at, color)
    local min, max = stingray.Gui.text_extents(gui, text, font, size)
    min = min + at
    max = max + at
    return max.x
end

local function hit_text(gui, pos, text, size, at)
    local min, max= stingray.Gui.text_extents(gui, text, font, size)
    if pos.x < at.x + min.x then return false end
    if pos.x > at.x + max.x then return false end
    if pos.y < at.y + min.y then return false end
    if pos.y > at.y + max.y then return false end
    return true
end

 --A helper function for displaying and interacting with 
 --the overlayed menu.  If the menu is visible and a menu item is 
 --selected it will return the specified key value. 
 --If the menu is hidden, this code will return the 
 --key pressed, if any, when executed.
function UI:display_menu(t)
    local w,h = stingray.Application.back_buffer_size()
    local key_x = 50
    local desc_x = key_x + 60
    local param_x = desc_x + 170
    local title_y = h-65
    local y = title_y - 50
    local font_size = 16
    local title_font_size = 40
    local line_height = 20  

    local key_color = stingray.Color(255,255,255)
    local title_color = stingray.Color(255,255,255)
    local desc_color = stingray.Color(200,150,150)
    local selection_color = stingray.Color(200,255,0)
    local param_color = stingray.Color(150,150,200)
    local back_color = stingray.Color(128,0,0,0)
    local touch_color = stingray.Color(255,255,0,0)

    local result = nil

    local sel = self.current_menu_item
    if not sel then sel = 1 end
    if sel > #t.items then sel = 1 end
    if sel < 1 then sel = #t.items end

    local enabled_items = {}
    for i,item in ipairs(t.items or {}) do
        if not item.disabled then
            table.insert(enabled_items, item)
        end
    end

    local touch_pos = nil
    local touch_up
    local touch = Appkit.Util.touch_interface()

    if Appkit.Util.use_touch() then
        sel = nil
        if touch.num_contacts() > 0 then
            local id = touch.contacts()
            touch_pos = Appkit.Util.location(touch, id)
            touch_up = touch.is_touch_up(id)
        end
    end

    for i,item in ipairs(enabled_items) do
        local key = item.key or ""
        local desc = item.text or ""
        local enabled = item.enabled or true
        local param = tostring(item.param or "")

        y = y - line_height

        local ki = stingray.Keyboard.button_id(key)
        if ki and stingray.Keyboard.pressed(ki) then
            result = key
        end
    end

    local select = function (s)
        local b = stingray.Keyboard.button_id("enter") if b and stingray.Keyboard.pressed(b) then return true end
        local b = stingray.Pad1.button_id("cross") if b and stingray.Pad1.pressed(b) then return true end
        local b = stingray.Pad1.button_id("a") if b and stingray.Pad1.pressed(b) then return true end
        return touch_up
    end

    local down = function (s)
        local b = stingray.Keyboard.button_id("down") if b and stingray.Keyboard.pressed(b) then return true end
        local b = stingray.Pad1.button_id("d_down") if b and stingray.Pad1.pressed(b) then return true end
        local b = stingray.Pad1.button_id("down") if b and stingray.Pad1.pressed(b) then return true end
        return false
    end

    local up = function (s)
        local b = stingray.Keyboard.button_id("up") if b and stingray.Keyboard.pressed(b) then return true end
        local b = stingray.Pad1.button_id("d_up") if b and stingray.Pad1.pressed(b) then return true end
        local b = stingray.Pad1.button_id("up") if b and stingray.Pad1.pressed(b) then return true end
        return false
    end

    local help = function (s)
        local b = stingray.Keyboard.button_id("f1") if b and stingray.Keyboard.pressed(b) then return true end
        local b = stingray.Pad1.button_id("start") if b and stingray.Pad1.pressed(b) then return true end
        local b = stingray.Pad1.button_id("options") if b and stingray.Pad1.pressed(b) then return true end
        local w,h = stingray.Gui.resolution()
        for _,id in ipairs{touch.contacts()} do
            if touch.is_touch_down(id) and Appkit.Util.location(touch, id).y > h-50 then
                return true
            end
        end
        return false
    end

    if sel then
        self.current_menu_item = sel
    end
    return result
end

return UI