local cwd = (...):gsub('%.grid$', '') .. "." local Menu = require(cwd .. "parent") local GridBox = Menu:extend() function GridBox:new(menusystem, name, x, y, w, h, colNumber, lineNumber) self.view = {} self.view.slotNumber = colNumber * lineNumber self.view.colNumber = colNumber self.view.colNumber = lineNumber GridBox.super.new(self, menusystem, name, x, y, w, h) self.begin = 1 self.h = lineNumber * self.widget.h -- On fait en sorte que la hauteur self.w = colNumber * self.widget.w -- et la largeur -- soit un multiple du nombre de slot et de leur dimensions self.cursor = {} self.cursor.x = 0 self.cursor.y = 0 -- La gridbox possède la particularité de pouvoir fusioner des slots, on fait -- donc une liste de slots disponibles, qui serviront par la suite. self.slots = {} for i= 1, self.view.slotNumber do self.slots[i] = {} self.slots[i].height = 1 self.slots[i].width = 1 self.slots[i].isChild = 0 self.slots[i].widgetID = i end end function GridBox:updateWidgetSize() self.widget.h = math.floor( self.h / self.view.colNumber ) self.widget.w = math.floor( self.w / self.view.colNumber ) end function GridBox:getWidgetSize(id) local slot = self:getWidgetSlot(id) return self.slots[slot].width, self.slots[slot].height end function GridBox:getWidgetSlot(widgetID) local slot = 0 for i,v in ipairs(self.slots) do if (self.slots[i].widgetID == widgetID) then slot = i end end return slot end function GridBox:update(dt) self.begin = 1 local slotID = self:getSlotbyCoord(self.cursor.x, self.cursor.y) if self.slots[slotID].isChild > 0 then slotID = self.slots[slotID].isChild end self.widget.selected = self.slots[slotID].widgetID self.cursor.x, self.cursor.y = self:getCoord(slotID) end function GridBox:regenSlots() local widgetID = 1 for i,v in ipairs(self.slots) do if v.isChild == 0 and (widgetID <= #self.widget.list) then self.slots[i].widgetID = widgetID widgetID = widgetID + 1 end end end function GridBox:addCol(slotID) local col, line = self:getCoord(slotID) if (col + self.slots[slotID].width + 1) <= self.view.colNumber then slotChild = slotID + self.slots[slotID].width for i = 1, self.slots[slotID].height do self.slots[slotChild + ((i-1)* self.view.colNumber)].isChild = slotID end self.slots[slotID].width = self.slots[slotID].width + 1 end end function GridBox:addLine(slotID) local col, line = self:getCoord(slotID) if (line + self.slots[slotID].height + 1) <= self.view.colNumber then slotChild = slotID + (self.slots[slotID].height * self.view.colNumber) for i = 1, self.slots[slotID].width do self.slots[slotChild + (i-1)].isChild = slotID end self.slots[slotID].height = self.slots[slotID].height + 1 end end function GridBox:getCoord(id_selected) id_selected = id_selected - 1 -- On simplifie les calcul en prenant 0 comme départ local line, col line = math.floor(id_selected / self.view.colNumber) col = id_selected - (line * self.view.colNumber) return col, line end function GridBox:getSlotbyCoord(col, line) return (line * self.view.colNumber) + col + 1 end function GridBox:getSlot(widgetID) local slotID for i,v in ipairs(self.slots) do if v.widgetID == widgetID then return i end end return 0 end function GridBox:moveCursor(newcol, newline) local col, line = self.cursor.x, self.cursor.y local relcol, relline = newcol - col, newline - line self.cursor.x, self.cursor.y = newcol, newline while self.cursor.y < 0 do self.cursor.y = self.cursor.y + self.view.colNumber end while self.cursor.x < 0 do self.cursor.x = self.cursor.x + self.view.colNumber end while self.cursor.y >= self.view.colNumber do self.cursor.y = self.cursor.y - self.view.colNumber end while self.cursor.x >= self.view.colNumber do self.cursor.x = self.cursor.x - self.view.colNumber end previousSlot = self:getSlotbyCoord(col, line) newSlot = self:getSlotbyCoord(self.cursor.x, self.cursor.y) if (self.slots[newSlot].isChild > 0) or (self.slots[newSlot].widgetID > #self.widget.list) then if (self.slots[newSlot].isChild == previousSlot) or (self.slots[newSlot].widgetID > #self.widget.list) then self:moveCursor(self.cursor.x + relcol, self.cursor.y + relline) end end end function GridBox:keyreleased(key, code) slotID = self:getSlot(self.widget.selected) local col, line = self.cursor.x, self.cursor.y if key == 'left' then --self:moveCol(-1) self:moveCursor(col - 1, line) end if key == 'right' then --self:moveCol(1) self:moveCursor(col + 1, line) end if key == 'up' then self:moveCursor(col, line - 1) end if key == 'down' then self:moveCursor(col, line + 1) end if key == "A" and self.widget.selected <= #self.widget.list then self.widget.list[self.widget.selected]:action() end end function GridBox:mousemoved(x, y) local col, line = self:getCoord(self.widget.selected) local begincol, beginline = self:getCoord(self.begin) local newcol, newline local newselect, slotID newline = beginline + math.floor(y / self.widget.h) newcol = math.floor(x / self.widget.w) self.cursor.x = newcol self.cursor.y = newline if self.widget.selected < 1 then self.widget.selected = 1 end if self.widget.selected > #self.widget.list then self.widget.selected = #self.widget.list end end function GridBox:mousepressed(x, y, button, isTouch) local col, line = self:getCoord(self.widget.selected) local begincol, beginline = self:getCoord(self.begin) local newcol, newline local newselect, slotID newline = beginline + math.floor(y / self.widget.h) newcol = math.floor(x / self.widget.w) newselect = (newline * self.view.colNumber) + newcol + 1 if self.slots[newselect].isChild > 0 then slotID = self.slots[newselect].isChild else slotID = newselect end self.widget.selected = self.slots[slotID].widgetID if #self.widget.list > 0 and self.widget.selected > 1 and self.widget.selected <= #self.widget.list then self.widget.list[self.widget.selected]:action() end end function GridBox:draw() local widgety = self.y local widgetx = self.x self:regenSlots() -- On reget les slots au cas où :p for i,v in ipairs(self.slots) do if (v.isChild == 0) and (v.widgetID <= #self.widget.list) then --self.widget.list[v.widgetID]:draw(widgetx, widgety, self.widget.w * v.sizeW, self.widget.h * v.sizeH) if self.widget.selected == v.widgetID and self:haveFocus() == true then self.widget.list[v.widgetID]:drawSelected(widgetx, widgety, self.widget.w * v.sizeW, self.widget.h * v.sizeH) else self.widget.list[v.widgetID]:draw(widgetx, widgety, self.widget.w * v.sizeW, self.widget.h * v.sizeH) end end if (v.isChild > 0) and false then love.graphics.setColor(255,255,255,128) love.graphics.rectangle("fill", widgetx, widgety, self.widget.w, self.widget.h) end local col, line = self:getCoord(i) if (col == self.cursor.x) and (line == self.cursor.y) and false then love.graphics.setColor(255,255,0,128) love.graphics.rectangle("fill", widgetx, widgety, self.widget.w, self.widget.h) end --love.graphics.setColor(0,0,0,10) --love.graphics.rectangle("line", widgetx, widgety, self.widget.w, self.widget.h) widgetx = widgetx + self.widget.w if widgetx == (self.x + self.w) then widgetx = self.x widgety = widgety + self.widget.h end end end return GridBox