feat: refactor most menus

This commit is contained in:
Kazhnuz 2020-12-04 12:57:24 +01:00
parent 7e697c3628
commit a72dfc0711
4 changed files with 159 additions and 300 deletions

View file

@ -26,205 +26,115 @@ local cwd = (...):gsub('%.flowbox$', '') .. "."
local Menu = require(cwd .. "parent") local Menu = require(cwd .. "parent")
local FlowBox = Menu:extend() local FlowBox = Menu:extend()
local menuutils = require(cwd .. "widgets.utils") local View2D = require(cwd .. "utils.view2D")
-- INIT FUNCTIONS -- INIT FUNCTIONS
-- Initialize and configure the flowbox -- Initialize and configure the flowbox
function FlowBox:new(menusystem, name, x, y, w, h, slots_hor, slots_vert) function FlowBox:new(menusystem, name, x, y, w, h, slots_hor, slots_vert)
self.view = {} self.view = View2D(slots_hor, slots_vert)
self.view.slotNumber = slots_hor * slots_vert
self.view.lineNumber = slots_vert
self.view.colNumber = slots_hor
self.view.firstSlot = 1
FlowBox.super.new(self, menusystem, name, x, y, w, h) FlowBox.super.new(self, menusystem, name, x, y, w, h)
self.widget.h = math.floor( self.h / slots_vert ) self:setRealSize()
self.widget.w = math.floor( self.w / slots_hor ) end
self.h = slots_vert * self.widget.h -- On fait en sorte que la hauteur
self.w = slots_hor * self.widget.w -- et la largeur function FlowBox:setRealSize()
-- On fait en sorte que la hauteur et la largeur
-- soit un multiple du nombre de slot et de leur dimensions -- soit un multiple du nombre de slot et de leur dimensions
self:updateWidgetSize()
self.w = self.view.colNumber * self.widgetSize.w
self.h = self.view.lineNumber * self.widgetSize.h
end end
-- UPDATE FUNCTIONS -- UPDATE FUNCTIONS
-- Update the menu and its view -- Update the menu and its view
function FlowBox:updateWidgetSize() function FlowBox:updateWidgetSize()
self.widget.h = math.floor( self.h / self.view.lineNumber ) self.widgetSize.h = math.floor( self.h / self.view.lineNumber )
self.widget.w = math.floor( self.w / self.view.colNumber ) self.widgetSize.w = math.floor( self.w / self.view.colNumber )
end end
function FlowBox:update(dt) function FlowBox:update(dt)
self:updateView() self.view:updateFirstSlot(self.widget:getSelected())
end
function FlowBox:updateView()
local col, line = self:getCoord(self.widget.selected)
local begincol, beginline = self:getCoord(self.view.firstSlot)
if line < beginline then
beginline = line
end
if line > beginline + self.view.lineNumber - 1 then
beginline = line - self.view.lineNumber + 1
end
if beginline < 0 then
beginline = 0
end
self.view.firstSlot = beginline * self.view.colNumber + 1
end
-- INFO FUNCTIONS
-- Get informations
function FlowBox: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 end
-- CURSOR FUNCTIONS -- CURSOR FUNCTIONS
-- Handle the cursor in a 2D menu -- Handle the cursor in a 2D menu
function FlowBox:moveCursor(new_col, new_line) function FlowBox:moveCursor2D(new_col, new_line)
local col, line = self:getCoord(self.widget.selected) local lastcol, lastline = self.view:getCoord(self.widget:lenght())
local lastcol, lastline = self:getCoord(#self.widget.list)
new_line = utils.math.wrapAndLimit(new_line, 0, lastline)
if new_line < 0 then
new_line = lastline
end
if new_line > lastline then
new_line = 0
end
if (new_line == lastline) then if (new_line == lastline) then
if new_col < 0 then new_col = utils.math.wrapAndLimit(new_col, 0, lastcol)
new_col = lastcol
end
if new_col > lastcol then
if (line == lastline) then
new_col = 0
else
new_col = lastcol
end
end
else else
if new_col < 0 then new_col = utils.math.wrapAndLimit(new_col, 0, (self.view.colNumber - 1))
new_col = self.view.colNumber - 1
end
if new_col == self.view.colNumber then
new_col = 0
end
end end
self.widget.selected = (new_line * self.view.colNumber) + new_col + 1 self.widget:moveCursor((new_line * self.view.colNumber) + new_col + 1)
end end
-- KEYS FUNCTIONS -- KEYS FUNCTIONS
-- Handle the keyboard/controller inputs -- Handle the keyboard/controller inputs
function FlowBox:keyreleased(key, code) function FlowBox:moveByKeys(key)
local col, line = self:getCoord(self.widget.selected) local col, line = self.view:getCoord(self.widget:getSelected())
if key == 'left' then if key == 'left' then
self:moveCursor(col - 1, line) self:moveCursor2D(col - 1, line)
end end
if key == 'right' then if key == 'right' then
self:moveCursor(col + 1, line) self:moveCursor2D(col + 1, line)
end end
if key == 'up' then if key == 'up' then
self:moveCursor(col, line - 1) self:moveCursor2D(col, line - 1)
end end
if key == 'down' then if key == 'down' then
self:moveCursor(col, line + 1) self:moveCursor2D(col, line + 1)
end
if key == "A" then
if (self.widget.selected >= 1 and self.widget.selected <= #self.widget.list) then
self.widget.list[self.widget.selected]:action("key")
end
end end
end end
-- MOUSE FUNCTIONS -- POSITION FUNCTIONS
-- Handle the mouse/touch pointer -- Get a widget by a position.
function FlowBox:mousemoved(x, y)
local col, line = self:getCoord(self.widget.selected)
local begincol, beginline = self:getCoord(self.view.firstSlot)
local newcol, newline, widget_selected
newline = beginline + math.floor(y / self.widget.h)
newcol = math.floor(x / self.widget.w)
widget_selected = (newline * self.view.colNumber) + newcol + 1
if widget_selected >= 1 and widget_selected <= #self.widget.list then
self.widget.selected = widget_selected
self:getFocus()
end
end
function FlowBox:mousepressed(x, y, button, isTouch)
local col, line = self:getCoord(self.widget.selected)
local begincol, beginline = self:getCoord(self.view.firstSlot)
local newline, newcol, widget_selected
newline = beginline + math.floor(y / self.widget.h)
newcol = math.floor(x / self.widget.w)
widget_selected = (newline * self.view.colNumber) + newcol + 1
if widget_selected >= 1 and widget_selected <= #self.widget.list then
self.widget.selected = widget_selected
self:getFocus()
self.widget.list[self.widget.selected]:action("pointer")
end
function FlowBox:getWidgetAtPoint(x, y)
local col = math.floor(x / self.widgetSize.w)
local line = math.floor(y / self.widgetSize.h)
return self.view:getFromCoord(col, line)
end end
-- DRAW FUNCTIONS -- DRAW FUNCTIONS
-- Draw the menu and its content -- Draw the menu and its content
function FlowBox:draw() function FlowBox:draw()
self:updateView() self.view:updateFirstSlot(self.widget:getSelected())
local widgety = self.y local widgety = self.y
local widgetx = self.x local widgetx = self.x
for i,v in ipairs(self.widget.list) do
if (i >= self.view.firstSlot) and (i < self.view.firstSlot + self.view.slotNumber) then local listWidget = self.widget:getList(self.view.firstSlot, self.view.slotNumber)
v:draw(widgetx, widgety, self.widget.w, self.widget.h)
if self.widget.selected == i and self:haveFocus() == true then for _, widget in ipairs(listWidget) do
v:drawSelected(widgetx, widgety, self.widget.w, self.widget.h) widget:drawWidget(widgetx, widgety, self.w, self.widgetSize.h)
else
v:draw(widgetx, widgety, self.widget.w, self.widget.h) -- On calcule la position du prochain widget
end widgetx = widgetx + self.widgetSize.w
widgetx = widgetx + self.widget.w if widgetx >= (self.x + self.w) then
if widgetx == (self.x + self.w) then
widgetx = self.x widgetx = self.x
widgety = widgety + self.widget.h widgety = widgety + self.widgetSize.h
end end
end
end end
end end
function FlowBox:drawCursor() function FlowBox:getGraphicalCursorPosition()
self:updateView() self.view:updateFirstSlot(self.widget:getSelected())
local begincol, beginline = self:getCoord(self.view.firstSlot) local _, beginline = self.view:getCoord(self.view.firstSlot)
if (self.widget.selected >= 1 and self.widget.selected <= #self.widget.list) then local w, h = self:getWidgetSize()
local w, h = self:getWidgetSize() local col, line = self.view:getCoord(self.widget:getSelected())
local col, line = self:getCoord(self.widget.selected) local x = (col) * h
local x = (col) * h local y = (line - beginline) * h
local y = (line - beginline) * h return self.x + x, self.y + y, w, h
menuutils.drawCursor(self.x + x, self.y + y, w, h)
end
end end
return FlowBox return FlowBox

View file

@ -27,16 +27,15 @@ local Menu = require(cwd .. "parent")
local HListBox = Menu:extend() local HListBox = Menu:extend()
local menuutils = require(cwd .. "widgets.utils") local menuutils = require(cwd .. "widgets.utils")
local View1D = require(cwd .. "utils.view1D")
-- INIT FUNCTIONS -- INIT FUNCTIONS
-- Initialize and configure functions. -- Initialize and configure functions.
function HListBox:new(menusystem, name, x, y, w, h, slotNumber) function HListBox:new(menusystem, name, x, y, w, h, slotNumber)
self.view = {} self.view = View1D(slotNumber)
self.view.slotNumber = slotNumber
self.view.firstSlot = 1
HListBox.super.new(self, menusystem, name, x, y, w, h) HListBox.super.new(self, menusystem, name, x, y, w, h)
self.w = slotNumber * self.widget.w -- On fait en sorte que la hauteur self.w = slotNumber * self.widgetSize.w -- On fait en sorte que la hauteur
-- soit un multiple du nombre de slot et de leur hauteur -- soit un multiple du nombre de slot et de leur hauteur
end end
@ -44,105 +43,56 @@ end
-- Update the menu every step. -- Update the menu every step.
function HListBox:updateWidgetSize() function HListBox:updateWidgetSize()
self.widget.h = self.h self.widgetSize.h = self.h
self.widget.w = math.floor( self.w / self.view.slotNumber ) self.widgetSize.w = math.floor( self.w / self.view.slotNumber )
end end
function HListBox:update(dt) function HListBox:update(dt)
self:updateView() self.view:updateFirstSlot(self.widget:getSelected())
end
function HListBox:updateView()
if self.widget.selected < self.view.firstSlot then
self.view.firstSlot = self.widget.selected
end
if self.widget.selected > self.view.firstSlot + self.view.slotNumber - 1 then
self.view.firstSlot = self.widget.selected - self.view.slotNumber + 1
end
if self.view.firstSlot < 1 then
self.view.firstSlot = 1
end
end end
-- KEYBOARD FUNCTIONS -- KEYBOARD FUNCTIONS
-- Handle key check. -- Handle key check.
function HListBox:keyreleased(key, code) function HListBox:moveByKeys(key, code)
if key == 'left' then if key == 'left' then
self:moveCursor(self.widget.selected - 1) self.widget:moveCursor(-1)
end end
if key == 'right' then if key == 'right' then
self:moveCursor(self.widget.selected + 1) self.widget:moveCursor(1)
end
if key == "A" then
if (self.widget.selected >= 1 and self.widget.selected <= #self.widget.list) then
self.widget.list[self.widget.selected]:action("key")
end
end
if key == "B" then
if (self.widget.cancel >= 1 and self.widget.cancel <= #self.widget.list) then
self.widget.list[self.widget.cancel]:action("key")
end
end
end
-- MOUSE FUNCTIONS
-- Click and stuff like that.
function HListBox:mousemoved(x, y)
local widget_selected = self.view.firstSlot + math.floor(x / self.widget.w)
if widget_selected >= 1 and widget_selected <= #self.widget.list then
self.widget.selected = widget_selected
self:getFocus()
end end
end end
function HListBox:mousepressed(x, y, button, isTouch) -- POSITION FUNCTIONS
local widget_selected = self.view.firstSlot + math.floor(x / self.widget.w) -- Get a widget by a position.
if widget_selected >= 1 and widget_selected <= #self.widget.list then
self.widget.selected = widget_selected
self:getFocus()
if #self.widget.list > 0 then
self.widget.list[self.widget.selected]:action("pointer")
end
end
function HListBox:getWidgetAtPoint(x, y)
return (self.view.firstSlot + math.floor(x / self.widgetSize.w))
end end
-- DRAW FUNCTIONS -- DRAW FUNCTIONS
-- Draw the menu and its content -- Draw the menu and its content
function HListBox:draw() function HListBox:draw()
self:updateView() self.view:updateFirstSlot(self.widget:getSelected())
local widgetx = self.x local widgetx = self.x
for i,v in ipairs(self.widget.list) do
if (i >= self.view.firstSlot) and (i < self.view.firstSlot + self.view.slotNumber) then local listWidget = self.widget:getList(self.view.firstSlot, self.view.slotNumber)
v:draw(widgetx, self.y, self.widget.w, self.h)
if self.widget.selected == i and self:haveFocus() == true then for _, widget in ipairs(listWidget) do
v:drawSelected(widgetx, self.y, self.widget.w, self.h) widget:drawWidget(widgetx, self.y, self.widgetSize.w, self.h)
else widgetx = widgetx + self.widgetSize.w
v:draw(widgetx, self.y, self.widget.w, self.h)
end
widgetx = widgetx + self.widget.w
end
end end
end end
function HListBox:drawCursor() function HListBox:getGraphicalCursorPosition()
self:updateView() self.view:updateFirstSlot(self.widget:getSelected())
if (self.widget.selected >= 1 and self.widget.selected <= #self.widget.list) then local w, h = self:getWidgetSize()
local w, h = self:getWidgetSize() local x = (self.widget:getSelected() - self.view.firstSlot) * w
local x = (self.widget.selected - self.view.firstSlot) * w
menuutils.drawCursor(self.x + x,self.y, w, h) return self.x + x,self.y, w, h
end
end end
return HListBox return HListBox

View file

@ -27,16 +27,15 @@ local Menu = require(cwd .. "parent")
local ListBox = Menu:extend() local ListBox = Menu:extend()
local menuutils = require(cwd .. "widgets.utils") local menuutils = require(cwd .. "widgets.utils")
local View1D = require(cwd .. "utils.view1D")
-- INIT FUNCTIONS -- INIT FUNCTIONS
-- Initialize and configure functions. -- Initialize and configure functions.
function ListBox:new(menusystem, name, x, y, w, h, slotNumber) function ListBox:new(menusystem, name, x, y, w, h, slotNumber)
self.view = {} self.view = View1D(slotNumber)
self.view.slotNumber = slotNumber
self.view.firstSlot = 1
ListBox.super.new(self, menusystem, name, x, y, w, h) ListBox.super.new(self, menusystem, name, x, y, w, h)
self.h = slotNumber * self.widget.h -- On fait en sorte que la hauteur self.h = slotNumber * self.widgetSize.h -- On fait en sorte que la hauteur
-- soit un multiple du nombre de slot et de leur hauteur -- soit un multiple du nombre de slot et de leur hauteur
end end
@ -44,105 +43,55 @@ end
-- Update the menu every step. -- Update the menu every step.
function ListBox:updateWidgetSize() function ListBox:updateWidgetSize()
self.widget.h = math.floor( self.h / self.view.slotNumber ) self.widgetSize.h = math.floor( self.h / self.view.slotNumber )
self.widget.w = self.w self.widgetSize.w = self.w
end end
function ListBox:update(dt) function ListBox:update(dt)
self:updateView() self.view:updateFirstSlot(self.widget:getSelected())
end
function ListBox:updateView()
if self.widget.selected < self.view.firstSlot then
self.view.firstSlot = self.widget.selected
end
if self.widget.selected > self.view.firstSlot + self.view.slotNumber - 1 then
self.view.firstSlot = self.widget.selected - self.view.slotNumber + 1
end
if self.view.firstSlot < 1 then
self.view.firstSlot = 1
end
end end
-- KEYBOARD FUNCTIONS -- KEYBOARD FUNCTIONS
-- Handle input from keyboard/controllers. -- Handle input from keyboard/controllers.
function ListBox:keyreleased(key, code) function ListBox:moveByKeys(key)
if key == 'up' then if key == 'up' then
self:moveCursor(self.widget.selected - 1) self.widget:moveCursor(-1)
end end
if key == 'down' then if key == 'down' then
self:moveCursor(self.widget.selected + 1) self.widget:moveCursor(1)
end
if key == "A" then
if (self.widget.selected >= 1 and self.widget.selected <= #self.widget.list) then
self.widget.list[self.widget.selected]:action("key")
end
end
if key == "B" then
if (self.widget.cancel >= 1 and self.widget.cancel <= #self.widget.list) then
self.widget.list[self.widget.cancel]:action("key")
end
end
end
-- MOUSE FUNCTIONS
-- Handle input from pointers.
function ListBox:mousemoved(x, y)
local widget_selected = self.view.firstSlot + math.floor(y / self.widget.h)
if widget_selected >= 1 and widget_selected <= #self.widget.list then
self.widget.selected = widget_selected
self:getFocus()
end end
end end
function ListBox:mousepressed(x, y, button, isTouch) -- POSITION FUNCTIONS
local widget_selected = self.view.firstSlot + math.floor(y / self.widget.h) -- Get a widget by a position.
if widget_selected >= 1 and widget_selected <= #self.widget.list then
self.widget.selected = widget_selected
self:getFocus()
if #self.widget.list > 0 then
self.widget.list[self.widget.selected]:action("pointer")
end
end
function ListBox:getWidgetAtPoint(x, y)
return (self.view.firstSlot + math.floor(y / self.widgetSize.h))
end end
-- DRAW FUNCTIONS -- DRAW FUNCTIONS
-- draw the menu and the rest of content. -- draw the menu and the rest of content.
function ListBox:draw() function ListBox:draw()
self:updateView() self.view:updateFirstSlot(self.widget:getSelected())
local widgety = self.y local widgety = self.y
for i,v in ipairs(self.widget.list) do
if (i >= self.view.firstSlot) and (i < self.view.firstSlot + self.view.slotNumber) then local listWidget = self.widget:getList(self.view.firstSlot, self.view.slotNumber)
v:draw(self.x, widgety, self.w, self.widget.h)
if self.widget.selected == i and self:haveFocus() == true then for _, widget in ipairs(listWidget) do
v:drawSelected(self.x, widgety, self.w, self.widget.h) widget:drawWidget(self.x, widgety, self.w, self.widgetSize.h)
else widgety = widgety + self.widgetSize.h
v:draw(self.x, widgety, self.w, self.widget.h)
end
widgety = widgety + self.widget.h
end
end end
end end
function ListBox:drawCursor() function ListBox:getGraphicalCursorPosition()
self:updateView() self.view:updateFirstSlot(self.widget:getSelected())
if (self.widget.selected >= 1 and self.widget.selected <= #self.widget.list) then local w, h = self:getWidgetSize()
local w, h = self:getWidgetSize() local y = (self.widget:getSelected() - self.view.firstSlot) * h
local y = (self.widget.selected - self.view.firstSlot) * h
menuutils.drawCursor(self.x,self.y + y, w, h) return self.x,self.y + y, w, h
end
end end
return ListBox return ListBox

View file

@ -26,6 +26,7 @@ local GuiElement = require "birb.modules.menusystem.parent"
local Menu = GuiElement:extend() local Menu = GuiElement:extend()
local MenuModel = require "birb.modules.menusystem.menus.utils.menumodel" local MenuModel = require "birb.modules.menusystem.menus.utils.menumodel"
local menuUtils = require "birb.modules.menusystem.menus.widgets.utils"
-- INIT FUNCTIONS -- INIT FUNCTIONS
-- Initialize and configure functions. -- Initialize and configure functions.
@ -34,11 +35,55 @@ function Menu:new(menusystem, name, x, y, w, h)
self.menusystem = self:getGui() self.menusystem = self:getGui()
self.widget = MenuModel() self.widget = MenuModel()
self.widgetSize = {}
self:updateWidgetSize() self:updateWidgetSize()
self:resetSound() self:resetSound()
end end
-- INTERACTION FUNCTIONS
-- Keyboard and mouse
function Menu:keyreleased(key)
self:moveByKeys(key)
self:actionAndCancel(key)
end
function Menu:mousemoved(x, y)
local widgetID = self:getWidgetAtPoint(x, y)
if (widgetID ~= nil) then
if self.widget:trySelectWidget(widgetID) then
self:getFocus()
end
end
end
function Menu:mousepressed(x, y, button, istouch)
local widgetID = self:getWidgetAtPoint(x, y)
if (widgetID ~= nil) then
if self.widget:trySelectWidget(widgetID) then
self:getFocus()
self.widget:action(widgetID, "pointer")
end
end
end
function Menu:moveByKeys(key)
-- Cette fonction ne contient rien par défaut
end
function Menu:actionAndCancel(key)
if key == "A" then
self.widget:selectedAction()
end
if key == "B" then
self.widget:cancelAction()
end
end
-- ACTION FUNCTIONS -- ACTION FUNCTIONS
-- Send actions to the widgets -- Send actions to the widgets
@ -69,12 +114,13 @@ end
function Menu:drawElement() function Menu:drawElement()
self:draw() self:draw()
if (self:haveFocus()) then if (self:haveFocus()) then
self:drawCursor() local x, y, w, h = self:getGraphicalCursorPosition()
self:drawGraphicalCursor(x, y, w, h)
end end
end end
function Menu:drawCursor() function Menu:drawGraphicalCursor(x, y, w, h)
-- nothing here menuUtils.drawCursor(x, y, w, h)
end end
function Menu:drawCanvas() function Menu:drawCanvas()
@ -93,18 +139,22 @@ function Menu:setCancelWidget(id)
end end
function Menu:updateWidgetSize() function Menu:updateWidgetSize()
self.widget.h = 0 self.widgetSize.h = 0
self.widget.w = 0 self.widgetSize.w = 0
end end
function Menu:getWidgetSize(id) function Menu:getWidgetSize(id)
return self.widget.w, self.widget.h return self.widgetSize.w, self.widgetSize.h
end end
function Menu:getWidgetNumber() function Menu:getWidgetNumber()
return self.widget:lenght() return self.widget:lenght()
end end
function Menu:getWidgetAtPoint(x, y)
end
-- CURSOR FUNCTIONS -- CURSOR FUNCTIONS
-- Set or move the cursor of the menu -- Set or move the cursor of the menu