Added generic layout class and HBox.

This commit is contained in:
2025-10-11 22:54:09 -04:00
parent 3f821d4258
commit 7cfffde56d
6 changed files with 212 additions and 79 deletions

62
src/ui/hbox.lua Normal file
View File

@@ -0,0 +1,62 @@
------------------------------------------------------------------------------
-- Imports
------------------------------------------------------------------------------
local make_class = require 'src.utils.classes'
local Layout = require 'src.ui.layout'
------------------------------------------------------------------------------
-- Class definitions
------------------------------------------------------------------------------
local HBox = make_class(Layout)
------------------------------------------------------------------------------
-- Class methods
------------------------------------------------------------------------------
function HBox:_init(x, y, w, h, spacing)
Layout._init(self, x, y, w, h, spacing)
end
function HBox:load()
Layout.load(self)
local _x = self.x
-- Load required assets if needed and then compute the coordinates of each button.
for _, v in pairs(self.elements) do
v.y = self.y
v.x = _x
_x = _x + v.w + self.s
end
end
function HBox:set_dimensions()
if self.w == nil then
self.w = 0
for i, v in pairs(self.elements) do
self.w = self.w + v.w
if i < #self.elements then self.w = self.w + self.s end
end
end
if self.h == nil then
self.h = 0
for _, v in pairs(self.elements) do
if v.h > self.h then self.h = v.h end
end
end
end
------------------------------------------------------------------------------
-- Module return
------------------------------------------------------------------------------
return HBox

96
src/ui/layout.lua Normal file
View File

@@ -0,0 +1,96 @@
------------------------------------------------------------------------------
-- Imports
------------------------------------------------------------------------------
local make_class = require 'src.utils.classes'
local UIElement = require 'src.ui.element'
------------------------------------------------------------------------------
-- Class definitions
------------------------------------------------------------------------------
local Layout = make_class(UIElement)
------------------------------------------------------------------------------
-- Class methods
------------------------------------------------------------------------------
function Layout:_init(x, y, w, h, spacing, float)
UIElement._init(self, x, y, float)
self.x = x ~= nil and x or 0
self.y = y ~= nil and y or 0
self.w = w
self.h = h
self.s = spacing ~= nil and spacing or 10
self.elements = {}
end
function Layout:add(element)
table.insert(self.elements, element)
end
function Layout:load()
-- Load required assets if needed and then compute the coordinates of each button.
for _, v in pairs(self.elements) do
if v.is_a[UIElement] then
v:load()
end
end
self:set_dimensions()
end
function Layout:unload()
for _, v in pairs(self.elements) do
if v.is_a[UIElement] then
v:unload()
end
end
end
function Layout:update(dt)
for _, v in pairs(self.elements) do
v:update(dt)
end
end
function Layout:draw()
for _, v in pairs(self.elements) do
v:draw()
end
end
function Layout:mousemoved(x, y, dx, dy)
for _, v in pairs(self.elements) do
v:mousemoved(x, y, dx, dy)
end
end
function Layout:mousepressed(x, y, btn)
for _, v in pairs(self.elements) do
v:mousepressed(x, y, btn)
end
end
function Layout:mousereleased(x, y, btn)
for _, v in pairs(self.elements) do
v:mousereleased(x, y, btn)
end
end
------------------------------------------------------------------------------
-- Module return
------------------------------------------------------------------------------
return Layout

View File

@@ -3,17 +3,14 @@
------------------------------------------------------------------------------
local make_class = require 'src.utils.classes'
local Asset = require 'src.utils.asset'
local Drawable = require 'src.graphics.drawable'
local Label = require 'src.ui.label'
local TextButton = require 'src.ui.textbtn'
local Layout = require 'src.ui.layout'
------------------------------------------------------------------------------
-- Class definitions
------------------------------------------------------------------------------
local VBox = make_class(Drawable, Asset)
local VBox = make_class(Layout)
------------------------------------------------------------------------------
@@ -21,36 +18,19 @@ local VBox = make_class(Drawable, Asset)
------------------------------------------------------------------------------
function VBox:_init(x, y, w, h, spacing)
self.x = x ~= nil and x or 0
self.y = y ~= nil and y or 0
self.w = w ~= nil and w or 0
self.h = h ~= nil and h or 0
self.s = spacing ~= nil and spacing or 10
self.elements = {}
end
function VBox:add_text_button(text, font, callback, float, base_col, sel_color, press_col)
table.insert(self.elements, TextButton(text, font, 0, 0, callback, float, base_col, sel_color, press_col))
end
function VBox:add_label(text, font, color, float)
table.insert(self.elements, Label(0, 0, text, font, color, float))
Layout._init(self, x, y, w, h, spacing)
end
function VBox:load()
Layout.load(self)
local _y = self.y
-- Load required assets if needed and then compute the coordinates of each button.
for _, v in pairs(self.elements) do
if v.is_a[Asset] then
v:load()
end
if v.float_right then
v.x = self.w - self.x - v.w
v.x = self.w - v.w
else
v.x = self.x
end
@@ -61,50 +41,23 @@ function VBox:load()
end
function VBox:unload()
for _, v in pairs(self.elements) do
if v.is_a[Asset] then
v:unload()
function VBox:set_dimensions()
if self.w == nil then
self.w = 0
for _, v in pairs(self.elements) do
if v.w > self.w then self.w = v.w end
end
end
if self.h == nil then
self.h = 0
for i, v in pairs(self.elements) do
self.h = self.h + v.h
if i < #self.elements then self.h = self.h + self.s end
end
end
end
function VBox:update(dt)
for _, v in pairs(self.elements) do
v:update(dt)
end
end
function VBox:draw()
for _, v in pairs(self.elements) do
v:draw()
end
end
function VBox:mousemoved(x, y, dx, dy)
for _, v in pairs(self.elements) do
v:mousemoved(x, y, dx, dy)
end
end
function VBox:mousepressed(x, y, btn)
for _, v in pairs(self.elements) do
v:mousepressed(x, y, btn)
end
end
function VBox:mousereleased(x, y, btn)
for _, v in pairs(self.elements) do
v:mousereleased(x, y, btn)
end
end
------------------------------------------------------------------------------
-- Module return
------------------------------------------------------------------------------