Created
July 14, 2020 21:39
-
-
Save art-solopov/e1609143546d3b42467bed9e096ad941 to your computer and use it in GitHub Desktop.
Basics of an UI drawing library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class = require('30log') | |
inspect = require('inspect') | |
local ui_draw = {} | |
local TILE_POSITIONS = { | |
left = 0, mid = 1, right = -1, | |
top = 0, mid = 1, bot = -1 | |
} | |
local UiElement = class( | |
'UiElement', | |
{ | |
tileSize = 16, tileStyles = {}, | |
tilePositions = { {'left', 'mid', 'right'}, {'top', 'mid', 'bot'} } | |
} | |
) | |
function getCoord(pos, origin, rightmost, tileSize) | |
local offset = TILE_POSITIONS[pos] | |
local coord = offset * tileSize | |
if offset < 0 then coord = rightmost + coord | |
else coord = origin + coord end | |
return coord | |
end | |
function UiElement:prepareTiles() | |
self.tiles = {} | |
for styleName, coords in pairs(self.tileStyles) do | |
local originX, originY = coords[1][1], coords[1][2] | |
local brX, brY = coords[2][1], coords[2][2] | |
for _i, xPos in ipairs(self.tilePositions[1]) do | |
for _j, yPos in ipairs(self.tilePositions[2]) do | |
local tileName = styleName .. "-" .. xPos .. "-" .. yPos | |
local tileX = getCoord(xPos, originX, brX, self.tileSize) | |
local tileY = getCoord(yPos, originY, brY, self.tileSize) | |
print(tileName, tileX, tileY) | |
local tile = love.graphics.newQuad( | |
tileX, tileY, | |
self.tileSize, self.tileSize, | |
self.texture:getDimensions() | |
) | |
self.tiles[tileName] = tile | |
end | |
end | |
end | |
end | |
function UiElement:isHover(x, y) | |
return x > self.x and x < self.x + self.width and | |
y > self.y and y < self.y + self.height | |
end | |
function UiElement:style() | |
return "default" | |
end | |
function UiElement:draw() | |
-- Override in subclasses | |
end | |
local Button = UiElement:extend("Button", { | |
isPressed = false, | |
fg = {1, 1, 1}, | |
tileStyles = { | |
default = { { 0, 0 }, { 190, 48 } }, | |
pressed = { { 0, 49 }, { 190, 94 } } | |
} | |
}) | |
function Button:draw() | |
local xTiles = self.width / self.tileSize | |
local yTiles = self.height / self.tileSize | |
local style = self:style() | |
for i=1,xTiles do | |
local xtName = "" | |
if i == 1 then xtName = "left" | |
elseif i == xTiles then xtName = "right" | |
else xtName = "mid" | |
end | |
for j=1,yTiles do | |
local ytName = "" | |
if j == 1 then ytName = "top" | |
elseif j == yTiles then ytName = "bot" | |
else ytName = "mid" | |
end | |
local tileName = style .. "-" .. xtName .. "-" .. ytName | |
local tile = self.tiles[tileName] | |
love.graphics.draw(self.texture, self.tiles[tileName], | |
self.x + (i - 1) * self.tileSize, | |
self.y + (j - 1) * self.tileSize) | |
end | |
end | |
love.graphics.setColor(self.fg) | |
love.graphics.printf(self.label, self.x, | |
self.y + 0.5 * self.height - 10, | |
self.width, "center") | |
end | |
function Button:onMousePress() | |
self.isPressed = true | |
end | |
function Button:onMouseRelease() | |
self.isPressed = false | |
end | |
function Button:style() | |
if self.isPressed then return "pressed" | |
else return self.super:style() | |
end | |
end | |
local btnPressMe = Button() | |
btnPressMe.x = 600 | |
btnPressMe.y = 200 | |
btnPressMe.width = 160 | |
btnPressMe.height = 48 | |
btnPressMe.label = "Press Me" | |
btnPressMe.onClick = function() print("Button pressed!") end | |
local btnQuit = Button() | |
btnQuit.x = 600 | |
btnQuit.y = 400 | |
btnQuit.width = 160 | |
btnQuit.height = 48 | |
btnQuit.fg = {1, 1, 1} | |
btnQuit.label = "Quit" | |
btnQuit.onClick = function() love.event.quit() end | |
ui_draw.ui = { btnQuit, btnPressMe } | |
function ui_draw:prepare() | |
self.canvas = love.graphics.newCanvas() | |
UiElement.texture = love.graphics.newImage("assets/blueSheet.png") | |
Button:prepareTiles() | |
end | |
function ui_draw:draw_ui() | |
-- Button test | |
local i = 0 | |
for name, quad in pairs(Button.tiles) do | |
y = 50 + i * (Button.tileSize + 3) | |
love.graphics.setColor(1, 1, 1) | |
love.graphics.draw(Button.texture, quad, 10, y) | |
love.graphics.setColor(0, 0, 0) | |
love.graphics.print(name, 30, y) | |
i = i + 1 | |
end | |
love.graphics.setColor(1, 1, 1) | |
love.graphics.setCanvas(self.canvas) | |
for _i, element in ipairs(ui_draw.ui) do | |
element:draw() | |
end | |
love.graphics.setCanvas() | |
love.graphics.draw(self.canvas) | |
end | |
function ui_draw:processMousePressed(x, y, button, presses) | |
for _i, element in ipairs(ui_draw.ui) do | |
if element:isHover(x, y) then | |
if button == 1 and element.onMousePress then element:onMousePress() end | |
break | |
end | |
end | |
end | |
function ui_draw:processMouseRelease(x, y, button, presses) | |
for _i, element in ipairs(ui_draw.ui) do | |
if element:isHover(x, y) then | |
if button == 1 and element.onMouseRelease then element:onMouseRelease() end | |
if button == 1 and element.onClick then element:onClick() end | |
break | |
end | |
end | |
end | |
function ui_draw:processMouseMove(x, y) | |
for _i, element in ipairs(self.ui) do | |
if element:isHover(x, y) then self.currentFocus = element end | |
break | |
end | |
end | |
return ui_draw |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment