From 3ae96e4cfc56f9d004dc8a478207a11fc33f028c Mon Sep 17 00:00:00 2001 From: Kazhnuz Date: Sat, 5 Dec 2020 09:01:41 +0100 Subject: [PATCH] feat: add a page system to menus --- birb/modules/menusystem/menus/model/init.lua | 166 +++++++++-------- birb/modules/menusystem/menus/model/page.lua | 185 +++++++++++++++++++ birb/modules/menusystem/menus/parent.lua | 31 ++++ 3 files changed, 307 insertions(+), 75 deletions(-) create mode 100644 birb/modules/menusystem/menus/model/page.lua diff --git a/birb/modules/menusystem/menus/model/init.lua b/birb/modules/menusystem/menus/model/init.lua index 96e8c01..179c87f 100644 --- a/birb/modules/menusystem/menus/model/init.lua +++ b/birb/modules/menusystem/menus/model/init.lua @@ -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]) - end - - return listWidget + local page = self:getCurrentPage() + return page:getList(first, lenght) 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 diff --git a/birb/modules/menusystem/menus/model/page.lua b/birb/modules/menusystem/menus/model/page.lua new file mode 100644 index 0000000..e6a0496 --- /dev/null +++ b/birb/modules/menusystem/menus/model/page.lua @@ -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 diff --git a/birb/modules/menusystem/menus/parent.lua b/birb/modules/menusystem/menus/parent.lua index ca0f890..9713fb8 100644 --- a/birb/modules/menusystem/menus/parent.lua +++ b/birb/modules/menusystem/menus/parent.lua @@ -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