local cwd = (...):gsub('%.grid$', '') .. "." local Menu = require(cwd .. "parent") GridBox = Menu:extend() function GridBox:new(menusystem, name, x, y, w, h, slots_hor, slots_vert) self.slots = slots_hor * slots_vert self.slots_hor = slots_hor self.slots_vert = slots_vert GridBox.super.new(self, menusystem, name, x, y, w, h) self.begin = 1 self.h = slots_vert * self.widget.h -- On fait en sorte que la hauteur self.w = slots_hor * 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.listSlot = {} for i= 1, self.slots do self.listSlot[i] = {} self.listSlot[i].sizeH = 1 self.listSlot[i].sizeW = 1 self.listSlot[i].isSlave = 0 self.listSlot[i].widgetID = i end end function GridBox:updateWidgetSize() self.widget.h = math.floor( self.h / self.slots_vert ) self.widget.w = math.floor( self.w / self.slots_hor ) end function GridBox:update(dt) self.begin = 1 local slotID = self:getSlotbyCoord(self.cursor.x, self.cursor.y) if self.listSlot[slotID].isSlave > 0 then slotID = self.listSlot[slotID].isSlave end self.widget.selected = self.listSlot[slotID].widgetID self.cursor.x, self.cursor.y = self:getCoord(slotID) end function GridBox:regenSlots() local widgetID = 1 for i,v in ipairs(self.listSlot) do if v.isSlave == 0 and (widgetID <= #self.widget.list) then self.listSlot[i].widgetID = widgetID widgetID = widgetID + 1 end end end function GridBox:addCol(slotID) local col, line = self:getCoord(slotID) if (col + self.listSlot[slotID].sizeW + 1) <= self.slots_hor then slotSlave = slotID + self.listSlot[slotID].sizeW for i = 1, self.listSlot[slotID].sizeH do self.listSlot[slotSlave + ((i-1)* self.slots_hor)].isSlave = slotID end self.listSlot[slotID].sizeW = self.listSlot[slotID].sizeW + 1 end end function GridBox:addLine(slotID) local col, line = self:getCoord(slotID) if (line + self.listSlot[slotID].sizeH + 1) <= self.slots_vert then slotSlave = slotID + (self.listSlot[slotID].sizeH * self.slots_hor) for i = 1, self.listSlot[slotID].sizeW do self.listSlot[slotSlave + (i-1)].isSlave = slotID end self.listSlot[slotID].sizeH = self.listSlot[slotID].sizeH + 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.slots_hor) col = id_selected - (line * self.slots_hor) return col, line end function GridBox:getSlotbyCoord(col, line) return (line * self.slots_hor) + col + 1 end function GridBox:getSlot(widgetID) local slotID for i,v in ipairs(self.listSlot) 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.slots_vert end while self.cursor.x < 0 do self.cursor.x = self.cursor.x + self.slots_hor end while self.cursor.y >= self.slots_vert do self.cursor.y = self.cursor.y - self.slots_vert end while self.cursor.x >= self.slots_hor do self.cursor.x = self.cursor.x - self.slots_hor end previousSlot = self:getSlotbyCoord(col, line) newSlot = self:getSlotbyCoord(self.cursor.x, self.cursor.y) if (self.listSlot[newSlot].isSlave > 0) or (self.listSlot[newSlot].widgetID > #self.widget.list) then if (self.listSlot[newSlot].isSlave == previousSlot) or (self.listSlot[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.slots_hor) + newcol + 1 if self.listSlot[newselect].isSlave > 0 then slotID = self.listSlot[newselect].isSlave else slotID = newselect end self.widget.selected = self.listSlot[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.listSlot) do if (v.isSlave == 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.isSlave > 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