ExperimentalGear/scripts/titlescreen/fields/service/listfield.lua

149 lines
4.1 KiB
Lua
Raw Normal View History

require("common.class")
local ContainerField = require("components.pager.containerfield")
local ServiceField = require("titlescreen.fields.service.servicefield")
---@class ListField: ContainerField, ServiceField
---@field selectedIndex integer
---@field locked boolean
---@field PADDING number[]
local ListField = {
__tostring = function() return "ListField" end,
MARGIN = {0, 0, 0, 0}, --{left, top, right, bottom}
PADDING = {0, 0, 0, 0}, --{left, top, right, bottom}
}
---Create a new ListField instance
---@param o? table # initial parameters
---@return ListField
function ListField:new(o)
o = o or {}
--set instance members
o.selectedIndex = o.selectedIndex or 1
o.locked = o.locked or false
local this = Inherit(self, o, ContainerField, ServiceField)
local minW = this.MARGIN[1] + this.PADDING[1] + this.PADDING[3] + this.MARGIN[3]
local minH = this.MARGIN[2] + this.PADDING[2] + this.PADDING[4] + this.MARGIN[4]
this.aabbW = math.max(this.aabbW, minW)
this.aabbH = math.max(this.aabbH, minH)
return this
end
---@param obj? any # message object for the field
function ListField:focus(obj)
if self._state == ServiceFieldState.ACTIVE then
return
end
-- if obj message received about direction of cursor movement
if obj and obj.direction then
if obj.direction > 0 then
self.selectedIndex = 1
elseif obj.direction < 0 then
self.selectedIndex = #self.content
end
end
-- else try to figure out by comparing current selected index
if self.selectedIndex < 1 then
self.selectedIndex = 1
elseif self.selectedIndex > #self.content then
self.selectedIndex = #self.content
end
local field = self.content[self.selectedIndex]
if field and field.focus then
field:focus()
end
ServiceField.focus(self)
end
---Add field to list container
---@param field Field
function ListField:addField(field)
--update size
self.aabbH = self.aabbH + field.aabbH
local fieldAabbW = self.PADDING[1] + field.aabbW + self.PADDING[3]
if self.aabbW < fieldAabbW then
self.aabbW = fieldAabbW
end
--add field to container
ContainerField.addField(self, field)
end
---Refresh content parameters
function ListField:refreshFields()
local aabbH = self.MARGIN[2] + self.PADDING[2] + self.PADDING[4] + self.MARGIN[4]
for _, child in ipairs(self.content) do
--update size
aabbH = aabbH + child.aabbH
local fieldAabbW = self.PADDING[1] + child.aabbW + self.PADDING[3]
if self.aabbW < fieldAabbW then
self.aabbW = fieldAabbW
end
end
self.aabbH = aabbH
ContainerField.refreshFields(self)
end
---@param button integer # options are under the `game` table prefixed with `BUTTON`
---@return boolean # true if further button input processing should be stopped, otherwise false
function ListField:handleButtonInput(button)
local field = self.content[self.selectedIndex]
if field:handleButtonInput(button) then
return true
end
if button == game.BUTTON_BCK then
local viewHandler = self:getParentPage().viewHandler
if viewHandler then
viewHandler:back()
end
return true
end
if self.locked then
return true
end
local direction = 0
if button == game.BUTTON_BTA then
direction = -1
elseif button == game.BUTTON_BTB then
direction = 1
end
if direction ~= 0 then
field:deactivate()
self.selectedIndex = self.selectedIndex + direction
if self.selectedIndex < 1 or self.selectedIndex > #self.content then
return false
end
field = self.content[self.selectedIndex]
field:focus()
end
return true
end
---@param deltaTime number # frametime in seconds
function ListField:drawContent(deltaTime)
gfx.Translate(self.PADDING[1] + self.MARGIN[1], self.PADDING[2] + self.MARGIN[2])
for _, child in ipairs(self.content) do
child:render(deltaTime)
gfx.Translate(0, child.aabbH)
end
end
return ListField