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

146 lines
4.0 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
local ListField = {
__tostring = function() return "ListField" end,
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
2022-04-12 01:03:37 +02:00
return Inherit(self, o, ContainerField, ServiceField)
end
---Initialize members
---@return ListField
function ListField:init()
ServiceField.init(self)
ContainerField.init(self)
local minW = self.MARGIN[1] + self.PADDING[1] + self.PADDING[3] + self.MARGIN[3]
local minH = self.MARGIN[2] + self.PADDING[2] + self.PADDING[4] + self.MARGIN[4]
self.aabbW = math.max(self.aabbW, minW)
self.aabbH = math.max(self.aabbH, minH)
return self
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)
--place field to correct position
field.posX = self.PADDING[1]
field.posY = self.aabbH - self.PADDING[4]
--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 posY = self.PADDING[1]
local aabbH = self.MARGIN[2] + self.PADDING[2] + self.PADDING[4] + self.MARGIN[4]
for _, child in ipairs(self.content) do
--place field to correct position
child.posX = self.PADDING[1]
child.posY = posY
posY = posY + child.aabbH
--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 and field.handleButtonInput then
if field:handleButtonInput(button) then
return true
end
end
local direction = 0
if button == game.BUTTON_BCK then
local viewHandler = self:getParentPage().viewHandler
if viewHandler then
viewHandler:back()
end
elseif 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
return ListField