added base classes for service page management

This commit is contained in:
Hersi 2022-03-30 02:53:27 +02:00
parent 9dffa1332a
commit 819b220357
4 changed files with 179 additions and 0 deletions

View File

@ -0,0 +1,51 @@
local dim = require("common.dimensions")
PAGE_DEFAULT_FONT_SIZE = 24
PAGE_DEFAULT_FONT_FACE = "dfmarugoth.ttf"
PAGE_DEFAULT_FONT_COLOR = {255, 255, 255, 255}
PAGE_DEFAULT_MARGIN = {72, 24, 0, 56} --{left, top, right, bottom}
PAGE_DEFAULT_SPACING = 4
PAGE_DEFAULT_FOOTER = {
"BT-A/BT-B = UP/DOWN",
"START = SELECT",
"BACK = RETURN TO LAST PAGE"
}
function DrawPageFooter(footer)
local bottomPageMargin = PAGE_DEFAULT_MARGIN[4]
local lineHeight = PAGE_DEFAULT_FONT_SIZE + PAGE_DEFAULT_SPACING
gfx.BeginPath()
gfx.FontSize(PAGE_DEFAULT_FONT_SIZE)
gfx.LoadSkinFont(PAGE_DEFAULT_FONT_FACE)
gfx.FillColor(table.unpack(PAGE_DEFAULT_FONT_COLOR))
gfx.TextAlign(gfx.TEXT_ALIGN_CENTER | gfx.TEXT_ALIGN_BOTTOM)
if type(footer) == "table" then
for index, line in ipairs(footer) do
local yFooterBase = dim.design.height - bottomPageMargin - #footer * lineHeight
gfx.Text(line, 1080 / 2, yFooterBase + (index-1) * lineHeight)
end
elseif type(footer) == "string" then
local yFooterBase = dim.design.height - bottomPageMargin
gfx.Text(footer, 1080 / 2, yFooterBase)
end
end
---Default button input handler
---@param page Page
---@param button integer
function HandlePageButtonInput(page, button)
local direction = 0
if button == game.BUTTON_BCK then
page.viewHandler:back()
return
end
if button == game.BUTTON_BTA then
direction = -1
elseif button == game.BUTTON_BTB then
direction = 1
end
page.selectedIdx = (page.selectedIdx - 1 + direction) % #page.fields + 1
end

View File

@ -0,0 +1,29 @@
require("titlescreen.service.common")
---@class Field
local Field = {
label = "",
parent = nil, ---@type Page
drawCustomFooter = nil, ---@type function void()
handleButtonInput = nil, ---@type function void(integer number)
handleKnobInput = nil, ---@type function void(integer knob, number delta)
}
function Field:new(o, label)
o = o or {}
setmetatable(o, self)
self.__index = self
self.label = label or ""
return o
end
function Field:render(deltaTime)
gfx.BeginPath()
gfx.FontSize(PAGE_DEFAULT_FONT_SIZE)
gfx.LoadSkinFont(PAGE_DEFAULT_FONT_FACE)
gfx.FillColor(table.unpack(PAGE_DEFAULT_FONT_COLOR))
gfx.TextAlign(gfx.TEXT_ALIGN_LEFT | gfx.TEXT_ALIGN_BOTTOM)
gfx.Text("<undefined>", 0, 0)
end
return Field

View File

@ -0,0 +1,59 @@
require("titlescreen.service.common")
---@class Page
local Page = {
title = "",
selectedIdx = 0,
fields = {}, ---@type Field[]
footer = PAGE_DEFAULT_FOOTER,
viewHandler = nil ---@type PageView
}
function Page:new(o, parent, title)
o = o or {}
setmetatable(o, self)
self.__index = self
self.parent = parent or nil
self.title = title or ""
return o
end
---Add field to page
---@param field Field
function Page:addField(field)
field.parent = self
table.insert(self.fields, field)
end
function Page:handleButtonInput(button)
if self.fields[selectedIndex] and self.fields[selectedIndex].handleButtonInput then
self.fields[selectedIndex].handleButtonInput(button)
else
HandlePageButtonInput(self, button)
end
end
function Page:handleKnobInput(knob, delta)
if self.fields[selectedIndex] and self.fields[selectedIndex].handleKnobInput then
self.fields[selectedIndex].handleKnobInput(knob, delta)
end
end
function Page:render(deltaTime)
--render page stuff
---background
---header
---footer
if self.fields[selectedIndex] and self.fields[selectedIndex].drawCustomFooter then
self.fields[selectedIndex].drawCustomFooter()
else
DrawPageFooter(self.footer)
end
--render children
for _, field in ipairs(self.fields) do
field.render(deltaTime)
end
end
return Page

View File

@ -0,0 +1,40 @@
---@class PageView
local PageView = {
pageStack = {} ---@type Page[]
}
local function pushStack(t, o)
table.insert(t, 1, o)
end
local function popStack(t)
return table.remove(t, 1)
end
function PageView:new(o, rootPage)
o = o or {}
setmetatable(o, self)
self.__index = self
rootPage.viewHandler = self
pushStack(self.pageStack, rootPage)
end
---Navigate to page
---@param page Page
function PageView:navigate(page)
page.viewHandler = self
pushStack(self.pageStack, page)
end
function PageView:back()
self.pageStack[1].viewHandler = nil
popStack(self.pageStack)
end
function PageView:render(deltaTime)
if self.pageStack[1] then
self.pageStack[1].render(deltaTime)
end
end
return PageView