-- menusystem :: the controller of the menu system. This object handle the -- different menu objects --[[ Copyright © 2019 Kazhnuz Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ]] local cwd = (...):gsub('%.init$', '') .. "." local MenuSystem = Object:extend() -- Load the differents menu object to get an easy access MenuSystem.Parent = require(cwd .. "parent") MenuSystem.ListBox = require(cwd .. "listbox") MenuSystem.FlowBox = require(cwd .. "flowbox") MenuSystem.Grid = require(cwd .. "grid") -- load widgets object MenuSystem.Widget = require(cwd .. "widgets") -- INIT FUNCTIONS -- Initialize and configure the menu controller function MenuSystem:new(scene) self.scene = scene self.menus = {} self.focusedMenu = "" self.isActive = true self.lockWorld = false self.lockAssets = false end function MenuSystem:reset() self.menus = {} end -- ACTIVATION FUNCTIONS -- Activate and deactivate the whole menusystem function MenuSystem:activate() self.isActive = true if (self.lockWorld) then if (self.scene.world ~= nil) then self.scene.world:setActivity(false) end end if (self.lockAssets) then if (self.scene.assets ~= nil) then self.scene.assets:setActivity(false) end end end function MenuSystem:deactivate() self.isActive = false if (self.lockWorld) then if (self.scene.world ~= nil) then self.scene.world:setActivity(true) end end if (self.lockAssets) then if (self.scene.assets ~= nil) then self.scene.assets:setActivity(true) end end end function MenuSystem:getActiveState() return self.isActive end function MenuSystem:lockWorldWhenActive(state) self.lockWorld = state end function MenuSystem:lockAssetsWhenActive(state) self.lockAssets = state end -- MENUS FUNCTIONS -- Controle the menus of the menusystem function MenuSystem:addMenu(name, menu) self.menus[name] = menu end function MenuSystem:menuExist(name) return (self.menus[name] ~= nil) end function MenuSystem:switchMenu(menu) for k,v in pairs(self.menus) do if k == menu then v:getFocus() v:setVisibility(true) v:setActivity(true) else v:setVisibility(false) v:setActivity(false) end end end function MenuSystem:lockMenu(menu, lock) local lock = lock or true if self:menuExist(menu) then self.menus[menu]:lock(lock) end end function MenuSystem:lockMenuVisibility(menu, lock) local lock = lock or true if self:menuExist(menu) then self.menus[menu]:lockVisibility(lock) end end function MenuSystem:setMenuActivity(menu, activity) local activity = activity or true if self:menuExist(menu) then self.menus[menu]:setActivity(activity) if activity == true then -- if we make the menu active, he have to be visible too self.menus[menu]:setVisibility(true) end end end function MenuSystem:setMenuVisibility(menu, visibility) local visibility = visibility or true if self:menuExist(menu) then self.menus[menu]:setVisibility(visibility) end end function MenuSystem:setAllMenuVisibility(visibility) for k,v in pairs(self.menus) do v:setVisibility(visibility) end end function MenuSystem:setAllMenuActivity(activity) for k,v in pairs(self.menus) do v.isActive = activity end end function MenuSystem:removeDestroyedMenus() -- On retire les entitées marquées comme supprimées for k,v in pairs(self.menus) do if (v.isDestroyed == true) then self.menus[k] = nil end end end -- SOUND FUNCTIONS -- Add sounds to every menus function MenuSystem:setSoundFromSceneAssets(soundname) for k,v in pairs(self.menus) do v:setSoundFromSceneAssets(soundname) end end function MenuSystem:setSound(soundasset) for k,v in pairs(self.menus) do v:setSound(soundasset) end end -- UPDATE FUNCTIONS -- Update the menus of the menusystem function MenuSystem:update(dt) if (self.isActive) then self:removeDestroyedMenus() for k,v in pairs(self.menus) do v:update(dt) v:updateWidgets(dt) end if self.menus[self.focusedMenu] ~= nil then -- Only check buttons if the current focused menu is actually active if self.menus[self.focusedMenu].isActive then for k,v in pairs(self.keys) do if self.keys[k].isPressed then self.menus[self.focusedMenu]:keyreleased(k) end end end end end end -- MOUSE FUNCTIONS -- Send mouse inputs to the menu function MenuSystem:mousemoved(x, y, dx, dy) if (self.isActive) then for k,v in pairs(self.menus) do if v.isActive then if (x > v.x) and (x < v.x + v.w) and (y > v.y) and (y < v.y + v.h) then v:mousemoved(x - v.x, y - v.y) break; end end end end end function MenuSystem:mousepressed( x, y, button, istouch ) if (self.isActive) then for k,v in pairs(self.menus) do if v.isActive then if (x > v.x) and (x < v.x + v.w) and (y > v.y) and (y < v.y + v.h) then v:mousepressed(x - v.x, y - v.y, button, istouch ) break; end end end end end -- DRAW FUNCTIONS -- All functions to draw the menus of the menusystem function MenuSystem:getDrawList() local drawList = {} for k,v in pairs(self.menus) do local drawObject = {} drawObject.name = k drawObject.depth = v.depth table.insert(drawList, drawObject) end table.sort(drawList, function(a,b) return a.depth > b.depth end) return drawList end function MenuSystem:draw(dt) if (self.isActive) then -- Draw all the menus self.drawList = self:getDrawList() for i,v in ipairs(self.drawList) do local v2 = self.menus[v.name] if (v2.isVisible) then v2:draw(dt) end end if self.menus[self.focusedMenu] ~= nil then if (self.menus[self.focusedMenu].isVisible) then self.menus[self.focusedMenu]:drawCursor() end end end end return MenuSystem