feat: add a page system to menus

This commit is contained in:
Kazhnuz 2020-12-05 09:01:41 +01:00
parent e2d029ab0f
commit 3ae96e4cfc
3 changed files with 307 additions and 75 deletions

View file

@ -1,4 +1,5 @@
local MenuModel = Object:extend() local MenuModel = Object:extend()
local Page = require "birb.modules.menusystem.menus.model.page"
local function updateWidgetByOrder(a, b) local function updateWidgetByOrder(a, b)
if a.order ~= b.order then if a.order ~= b.order then
@ -12,6 +13,8 @@ end
-- Initialize and basic functions. -- Initialize and basic functions.
function MenuModel:new() function MenuModel:new()
self:clear()
self.list = {} self.list = {}
self.selected = 0 self.selected = 0
self.selectedPrevious = 0 self.selectedPrevious = 0
@ -21,152 +24,165 @@ function MenuModel:new()
end end
function MenuModel:clear() function MenuModel:clear()
self.list = {} self.pages = {}
self.cancel = 0 self:addPage("main")
end end
function MenuModel:setLimit(limit) -- PAGE FUNCTIONS
self.limit = limit -- 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 end
-- UPDATE/DRAW FUNCTIONS -- UPDATE/DRAW FUNCTIONS
-- All the update functions -- All the update functions
function MenuModel:update(dt) function MenuModel:update(dt)
self:removeDestroyedWidgets() local page = self:getCurrentPage()
for id, widget in ipairs(self.list) do page:update(dt)
widget.id = id
widget:update(dt)
end
end end
function MenuModel:updateWidgetsOrder() function MenuModel:updateWidgetsOrder()
table.sort(self.list, updateWidgetByOrder) local page = self:getCurrentPage()
page:updateWidgetByOrder()
end end
function MenuModel:updateWidgetsID() function MenuModel:updateWidgetsID()
for id, widget in ipairs(self.list) do local page = self:getCurrentPage()
widget.id = id page:updateWidgetsID()
end
end end
-- ACTION FUNCTIONS -- ACTION FUNCTIONS
-- All the actions callback used by the widgets -- All the actions callback used by the widgets
function MenuModel:cancelAction() function MenuModel:cancelAction()
if (self.cancel ~= 0) then local page = self:getCurrentPage()
self:action(self.cancel, "key") page:cancelAction()
end
end end
function MenuModel:action(id, type) function MenuModel:action(id, type)
if (self:widgetExist(id)) then local page = self:getCurrentPage()
self.list[id]:action(type) page:action(id, type)
end
end end
function MenuModel:selectedAction() function MenuModel:selectedAction()
if (self.selected ~= 0) then local page = self:getCurrentPage()
self:action(self.selected, "key") page:selectedAction()
end
end end
-- WIDGET FUNCTIONS -- WIDGET FUNCTIONS
-- All the functions to handle widgets -- All the functions to handle widgets
function MenuModel:addWidget(newWidget) function MenuModel:addWidget(newWidget)
if (self.limit ~= -1 and #self.list >= self.limit) then local page = self:getCurrentPage()
return page:addWidget(newWidget)
end
if #self.list == 0 then
self.selected = 1
end
table.insert(self.list, newWidget)
self:updateWidgetsID()
self:updateWidgetsOrder()
end end
function MenuModel:getList(first, lenght) function MenuModel:getList(first, lenght)
local listWidget = {} local page = self:getCurrentPage()
local first = first or 1 return page:getList(first, lenght)
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])
end end
return listWidget function MenuModel:removeDestroyedWidgets()
end local page = self:getCurrentPage()
page:removeDestroyedWidgets()
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
end end
function MenuModel:lenght() function MenuModel:lenght()
return #self.list local page = self:getCurrentPage()
return page:lenght()
end end
function MenuModel:widgetExist(id) function MenuModel:widgetExist(id)
local id = id or 0 local page = self:getCurrentPage()
return (id >= 1 and id <= #self.list) return page:widgetExist(id)
end
function MenuModel:setLimit(limit)
local page = self:getCurrentPage()
page:setLimit(limit)
end end
-- CANCEL FUNCTIONS -- CANCEL FUNCTIONS
-- Add a widget as a "cancel" function -- Add a widget as a "cancel" function
function MenuModel:setCancelWidget(id) function MenuModel:setCancelWidget()
self.cancel = #self.list local page = self:getCurrentPage()
page:setCancelWidget()
end end
function MenuModel:getCancelWidget(id) function MenuModel:getCancelWidget()
return self.cancel local page = self:getCurrentPage()
return page:getCancelWidget()
end end
-- CURSOR FUNCTIONS -- CURSOR FUNCTIONS
-- Set or move the cursor of the menu -- Set or move the cursor of the menu
function MenuModel:getSelected() function MenuModel:getSelected()
return self.selected local page = self:getCurrentPage()
return page:getSelected()
end end
function MenuModel:haveCursor() function MenuModel:haveCursor()
return self:widgetExist(self.selected) local page = self:getCurrentPage()
return page:haveCursor()
end end
function MenuModel:trySelectWidget(cursorid) function MenuModel:trySelectWidget(cursorid)
if (self:widgetExist(cursorid)) then local page = self:getCurrentPage()
self:setCursor(cursorid) return page:trySelectWidget(cursorid)
return true
else
return false
end
end end
function MenuModel:setCursor(cursorid) function MenuModel:setCursor(cursorid)
self.selected = cursorid --math.max(1, math.min(cursorid, #self.list)) local page = self:getCurrentPage()
page:setCursor(cursorid)
end end
function MenuModel:moveCursorAbsolute(newSelected) function MenuModel:moveCursorAbsolute(newSelected)
-- self:playNavigationSound() local page = self:getCurrentPage()
if newSelected < 1 then page:moveCursorAbsolute(newSelected)
self.selected = #self.list + newSelected
else
if newSelected > #self.list then
self.selected = newSelected - #self.list
else
self.selected = newSelected
end
end
end end
function MenuModel:moveCursor(relative) function MenuModel:moveCursor(relative)
self:moveCursorAbsolute(self.selected + relative) local page = self:getCurrentPage()
page:moveCursor(relative)
end end

View 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

View file

@ -84,6 +84,37 @@ function Menu:actionAndCancel(key)
end end
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 -- ACTION FUNCTIONS
-- Send actions to the widgets -- Send actions to the widgets