feat: add a page system to menus
This commit is contained in:
parent
e2d029ab0f
commit
3ae96e4cfc
3 changed files with 307 additions and 75 deletions
|
@ -1,4 +1,5 @@
|
|||
local MenuModel = Object:extend()
|
||||
local Page = require "birb.modules.menusystem.menus.model.page"
|
||||
|
||||
local function updateWidgetByOrder(a, b)
|
||||
if a.order ~= b.order then
|
||||
|
@ -12,6 +13,8 @@ end
|
|||
-- Initialize and basic functions.
|
||||
|
||||
function MenuModel:new()
|
||||
self:clear()
|
||||
|
||||
self.list = {}
|
||||
self.selected = 0
|
||||
self.selectedPrevious = 0
|
||||
|
@ -21,152 +24,165 @@ function MenuModel:new()
|
|||
end
|
||||
|
||||
function MenuModel:clear()
|
||||
self.list = {}
|
||||
self.cancel = 0
|
||||
self.pages = {}
|
||||
self:addPage("main")
|
||||
end
|
||||
|
||||
function MenuModel:setLimit(limit)
|
||||
self.limit = limit
|
||||
-- PAGE FUNCTIONS
|
||||
-- Handle pages
|
||||
|
||||
function MenuModel:addPage(pageName)
|
||||
local page = Page()
|
||||
self.pages[pageName] = page
|
||||
self.currentPage = pageName
|
||||
return page
|
||||
end
|
||||
|
||||
function MenuModel:addSubmenu(pageName, parent)
|
||||
local page = self:addPage(pageName)
|
||||
page:setParent(parent)
|
||||
end
|
||||
|
||||
function MenuModel:removePage(pageName)
|
||||
self.pages[pageName] = nil
|
||||
end
|
||||
|
||||
function MenuModel:pageExists(pageName)
|
||||
return (self.pages[pageName] ~= nil)
|
||||
end
|
||||
|
||||
function MenuModel:getPage(pageName)
|
||||
return self.pages[pageName]
|
||||
end
|
||||
|
||||
function MenuModel:switch(pageName)
|
||||
if (self:pageExists(pageName)) then
|
||||
self.currentPage = pageName
|
||||
end
|
||||
end
|
||||
|
||||
function MenuModel:back()
|
||||
local page = self:getCurrentPage()
|
||||
self:switch(page:getParent())
|
||||
end
|
||||
|
||||
function MenuModel:getCurrentPage()
|
||||
return self:getPage(self.currentPage)
|
||||
end
|
||||
|
||||
-- UPDATE/DRAW FUNCTIONS
|
||||
-- All the update functions
|
||||
|
||||
function MenuModel:update(dt)
|
||||
self:removeDestroyedWidgets()
|
||||
for id, widget in ipairs(self.list) do
|
||||
widget.id = id
|
||||
widget:update(dt)
|
||||
end
|
||||
local page = self:getCurrentPage()
|
||||
page:update(dt)
|
||||
end
|
||||
|
||||
function MenuModel:updateWidgetsOrder()
|
||||
table.sort(self.list, updateWidgetByOrder)
|
||||
local page = self:getCurrentPage()
|
||||
page:updateWidgetByOrder()
|
||||
end
|
||||
|
||||
function MenuModel:updateWidgetsID()
|
||||
for id, widget in ipairs(self.list) do
|
||||
widget.id = id
|
||||
end
|
||||
local page = self:getCurrentPage()
|
||||
page:updateWidgetsID()
|
||||
end
|
||||
|
||||
-- ACTION FUNCTIONS
|
||||
-- All the actions callback used by the widgets
|
||||
|
||||
function MenuModel:cancelAction()
|
||||
if (self.cancel ~= 0) then
|
||||
self:action(self.cancel, "key")
|
||||
end
|
||||
local page = self:getCurrentPage()
|
||||
page:cancelAction()
|
||||
end
|
||||
|
||||
function MenuModel:action(id, type)
|
||||
if (self:widgetExist(id)) then
|
||||
self.list[id]:action(type)
|
||||
end
|
||||
local page = self:getCurrentPage()
|
||||
page:action(id, type)
|
||||
end
|
||||
|
||||
function MenuModel:selectedAction()
|
||||
if (self.selected ~= 0) then
|
||||
self:action(self.selected, "key")
|
||||
end
|
||||
local page = self:getCurrentPage()
|
||||
page:selectedAction()
|
||||
end
|
||||
|
||||
-- WIDGET FUNCTIONS
|
||||
-- All the functions to handle widgets
|
||||
|
||||
function MenuModel:addWidget(newWidget)
|
||||
if (self.limit ~= -1 and #self.list >= self.limit) then
|
||||
return
|
||||
end
|
||||
if #self.list == 0 then
|
||||
self.selected = 1
|
||||
end
|
||||
table.insert(self.list, newWidget)
|
||||
self:updateWidgetsID()
|
||||
self:updateWidgetsOrder()
|
||||
local page = self:getCurrentPage()
|
||||
page:addWidget(newWidget)
|
||||
end
|
||||
|
||||
function MenuModel:getList(first, lenght)
|
||||
local listWidget = {}
|
||||
local first = first or 1
|
||||
local lenght = lenght or #self.list
|
||||
lenght = math.min(lenght, (#self.list + 1 - first))
|
||||
local last = (first + lenght - 1)
|
||||
|
||||
for i = first, (last) do
|
||||
table.insert(listWidget, self.list[i])
|
||||
local page = self:getCurrentPage()
|
||||
return page:getList(first, lenght)
|
||||
end
|
||||
|
||||
return listWidget
|
||||
end
|
||||
|
||||
function MenuModel:removeDestroyedWidgets() -- On retire les widgets marquées comme supprimées
|
||||
for i, v in ipairs(self.list) do
|
||||
if (v.destroyed == true) then
|
||||
table.remove(self.list, i)
|
||||
end
|
||||
end
|
||||
function MenuModel:removeDestroyedWidgets()
|
||||
local page = self:getCurrentPage()
|
||||
page:removeDestroyedWidgets()
|
||||
end
|
||||
|
||||
function MenuModel:lenght()
|
||||
return #self.list
|
||||
local page = self:getCurrentPage()
|
||||
return page:lenght()
|
||||
end
|
||||
|
||||
function MenuModel:widgetExist(id)
|
||||
local id = id or 0
|
||||
return (id >= 1 and id <= #self.list)
|
||||
local page = self:getCurrentPage()
|
||||
return page:widgetExist(id)
|
||||
end
|
||||
|
||||
function MenuModel:setLimit(limit)
|
||||
local page = self:getCurrentPage()
|
||||
page:setLimit(limit)
|
||||
end
|
||||
|
||||
-- CANCEL FUNCTIONS
|
||||
-- Add a widget as a "cancel" function
|
||||
|
||||
function MenuModel:setCancelWidget(id)
|
||||
self.cancel = #self.list
|
||||
function MenuModel:setCancelWidget()
|
||||
local page = self:getCurrentPage()
|
||||
page:setCancelWidget()
|
||||
end
|
||||
|
||||
function MenuModel:getCancelWidget(id)
|
||||
return self.cancel
|
||||
function MenuModel:getCancelWidget()
|
||||
local page = self:getCurrentPage()
|
||||
return page:getCancelWidget()
|
||||
end
|
||||
|
||||
-- CURSOR FUNCTIONS
|
||||
-- Set or move the cursor of the menu
|
||||
|
||||
function MenuModel:getSelected()
|
||||
return self.selected
|
||||
local page = self:getCurrentPage()
|
||||
return page:getSelected()
|
||||
end
|
||||
|
||||
function MenuModel:haveCursor()
|
||||
return self:widgetExist(self.selected)
|
||||
local page = self:getCurrentPage()
|
||||
return page:haveCursor()
|
||||
end
|
||||
|
||||
function MenuModel:trySelectWidget(cursorid)
|
||||
if (self:widgetExist(cursorid)) then
|
||||
self:setCursor(cursorid)
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
local page = self:getCurrentPage()
|
||||
return page:trySelectWidget(cursorid)
|
||||
end
|
||||
|
||||
function MenuModel:setCursor(cursorid)
|
||||
self.selected = cursorid --math.max(1, math.min(cursorid, #self.list))
|
||||
local page = self:getCurrentPage()
|
||||
page:setCursor(cursorid)
|
||||
end
|
||||
|
||||
function MenuModel:moveCursorAbsolute(newSelected)
|
||||
-- self:playNavigationSound()
|
||||
if newSelected < 1 then
|
||||
self.selected = #self.list + newSelected
|
||||
else
|
||||
if newSelected > #self.list then
|
||||
self.selected = newSelected - #self.list
|
||||
else
|
||||
self.selected = newSelected
|
||||
end
|
||||
end
|
||||
local page = self:getCurrentPage()
|
||||
page:moveCursorAbsolute(newSelected)
|
||||
end
|
||||
|
||||
function MenuModel:moveCursor(relative)
|
||||
self:moveCursorAbsolute(self.selected + relative)
|
||||
local page = self:getCurrentPage()
|
||||
page:moveCursor(relative)
|
||||
end
|
||||
|
||||
|
||||
|
|
185
birb/modules/menusystem/menus/model/page.lua
Normal file
185
birb/modules/menusystem/menus/model/page.lua
Normal file
|
@ -0,0 +1,185 @@
|
|||
local Page = Object:extend()
|
||||
|
||||
local function updateWidgetByOrder(a, b)
|
||||
if a.order ~= b.order then
|
||||
return a.order < b.order
|
||||
else
|
||||
return a.creationID < b.creationID
|
||||
end
|
||||
end
|
||||
|
||||
-- INIT FUNCTIONS
|
||||
-- Initialize and basic functions.
|
||||
|
||||
function Page:new()
|
||||
self.widgets = {}
|
||||
self.selected = 0
|
||||
self.selectedPrevious = 0
|
||||
self.cancel = 0
|
||||
self.limit = -1
|
||||
self.parent = nil
|
||||
-- self:updateWidgetSize()
|
||||
end
|
||||
|
||||
function Page:clear()
|
||||
self.widgets = {}
|
||||
self.cancel = 0
|
||||
end
|
||||
|
||||
function Page:setLimit(limit)
|
||||
self.limit = limit
|
||||
end
|
||||
|
||||
-- PAGE FUNCTIONS
|
||||
-- functions to handle other pages
|
||||
|
||||
function Page:setParent(parent)
|
||||
self.parent = parent
|
||||
end
|
||||
|
||||
function Page:getParent()
|
||||
return self.parent
|
||||
end
|
||||
|
||||
-- UPDATE/DRAW FUNCTIONS
|
||||
-- All the update functions
|
||||
|
||||
function Page:update(dt)
|
||||
self:removeDestroyedWidgets()
|
||||
for id, widget in ipairs(self.widgets) do
|
||||
widget.id = id
|
||||
widget:update(dt)
|
||||
end
|
||||
end
|
||||
|
||||
function Page:updateWidgetsOrder()
|
||||
table.sort(self.widgets, updateWidgetByOrder)
|
||||
end
|
||||
|
||||
function Page:updateWidgetsID()
|
||||
for id, widget in ipairs(self.widgets) do
|
||||
widget.id = id
|
||||
end
|
||||
end
|
||||
|
||||
-- ACTION FUNCTIONS
|
||||
-- All the actions callback used by the widgets
|
||||
|
||||
function Page:cancelAction()
|
||||
if (self.cancel ~= 0) then
|
||||
self:action(self.cancel, "key")
|
||||
end
|
||||
end
|
||||
|
||||
function Page:action(id, type)
|
||||
if (self:widgetExist(id)) then
|
||||
self.widgets[id]:action(type)
|
||||
end
|
||||
end
|
||||
|
||||
function Page:selectedAction()
|
||||
if (self.selected ~= 0) then
|
||||
self:action(self.selected, "key")
|
||||
end
|
||||
end
|
||||
|
||||
-- WIDGET FUNCTIONS
|
||||
-- All the functions to handle widgets
|
||||
|
||||
function Page:addWidget(newWidget)
|
||||
if (self.limit ~= -1 and #self.widgets >= self.limit) then
|
||||
return
|
||||
end
|
||||
if #self.widgets == 0 then
|
||||
self.selected = 1
|
||||
end
|
||||
table.insert(self.widgets, newWidget)
|
||||
self:updateWidgetsID()
|
||||
self:updateWidgetsOrder()
|
||||
end
|
||||
|
||||
function Page:getList(first, lenght)
|
||||
local listWidget = {}
|
||||
local first = first or 1
|
||||
local lenght = lenght or #self.widgets
|
||||
lenght = math.min(lenght, (#self.widgets + 1 - first))
|
||||
local last = (first + lenght - 1)
|
||||
|
||||
for i = first, (last) do
|
||||
table.insert(listWidget, self.widgets[i])
|
||||
end
|
||||
|
||||
return listWidget
|
||||
end
|
||||
|
||||
function Page:removeDestroyedWidgets() -- On retire les widgets marquées comme supprimées
|
||||
for i, v in ipairs(self.widgets) do
|
||||
if (v.destroyed == true) then
|
||||
table.remove(self.widgets, i)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Page:lenght()
|
||||
return #self.widgets
|
||||
end
|
||||
|
||||
function Page:widgetExist(id)
|
||||
local id = id or 0
|
||||
return (id >= 1 and id <= #self.widgets)
|
||||
end
|
||||
|
||||
-- CANCEL FUNCTIONS
|
||||
-- Add a widget as a "cancel" function
|
||||
|
||||
function Page:setCancelWidget(id)
|
||||
self.cancel = #self.widgets
|
||||
end
|
||||
|
||||
function Page:getCancelWidget(id)
|
||||
return self.cancel
|
||||
end
|
||||
|
||||
-- CURSOR FUNCTIONS
|
||||
-- Set or move the cursor of the menu
|
||||
|
||||
function Page:getSelected()
|
||||
return self.selected
|
||||
end
|
||||
|
||||
function Page:haveCursor()
|
||||
return self:widgetExist(self.selected)
|
||||
end
|
||||
|
||||
function Page:trySelectWidget(cursorid)
|
||||
if (self:widgetExist(cursorid)) then
|
||||
self:setCursor(cursorid)
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function Page:setCursor(cursorid)
|
||||
self.selected = cursorid --math.max(1, math.min(cursorid, #self.widgets))
|
||||
end
|
||||
|
||||
function Page:moveCursorAbsolute(newSelected)
|
||||
-- self:playNavigationSound()
|
||||
if newSelected < 1 then
|
||||
self.selected = #self.widgets + newSelected
|
||||
else
|
||||
if newSelected > #self.widgets then
|
||||
self.selected = newSelected - #self.widgets
|
||||
else
|
||||
self.selected = newSelected
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Page:moveCursor(relative)
|
||||
self:moveCursorAbsolute(self.selected + relative)
|
||||
end
|
||||
|
||||
|
||||
return Page
|
|
@ -84,6 +84,37 @@ function Menu:actionAndCancel(key)
|
|||
end
|
||||
end
|
||||
|
||||
-- PAGE FUNCTIONS
|
||||
-- Wrapper around pages functions from the model
|
||||
|
||||
function Menu:addPage(pageName)
|
||||
self.widget:addPage(pageName)
|
||||
end
|
||||
|
||||
function Menu:addSubmenu(pageName, parent)
|
||||
self.widget:addSubmenu(pageName, parent)
|
||||
end
|
||||
|
||||
function Menu:removePage(pageName)
|
||||
self.widget:removePage(pageName)
|
||||
end
|
||||
|
||||
function Menu:pageExists(pageName)
|
||||
return self.widget:pageExists(pageName)
|
||||
end
|
||||
|
||||
function Menu:getPage(pageName)
|
||||
self.widget:getPage(pageName)
|
||||
end
|
||||
|
||||
function Menu:switch(pageName)
|
||||
self.widget:switch(pageName)
|
||||
end
|
||||
|
||||
function Menu:back()
|
||||
self.widget:back()
|
||||
end
|
||||
|
||||
-- ACTION FUNCTIONS
|
||||
-- Send actions to the widgets
|
||||
|
||||
|
|
Loading…
Reference in a new issue