b3febf0fb3
Don't let every menus handle themselves if they have focus, it should be the menu system role to handle that
236 lines
7.1 KiB
Lua
236 lines
7.1 KiB
Lua
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
|