90 lines
3.4 KiB
Lua
90 lines
3.4 KiB
Lua
local Rect = require "lib.simple_ui.rect"
|
||
|
||
local function makeGradientMesh(w, h, topColor, bottomColor)
|
||
local vertices = {
|
||
{ 0, 0, 0, 0, topColor[1], topColor[2], topColor[3], topColor[4] }, -- левый верх
|
||
{ w, 0, 1, 0, topColor[1], topColor[2], topColor[3], topColor[4] }, -- правый верх
|
||
{ w, h, 1, 1, bottomColor[1], bottomColor[2], bottomColor[3], bottomColor[4] }, -- правый низ
|
||
{ 0, h, 0, 1, bottomColor[1], bottomColor[2], bottomColor[3], bottomColor[4] }, -- левый низ
|
||
}
|
||
local mesh = love.graphics.newMesh(vertices, "fan", "static")
|
||
return mesh
|
||
end
|
||
|
||
--- @class UIElement
|
||
--- @field bounds Rect Прямоугольник, в границах которого размещается элемент. Размеры и положение в экранных координатах
|
||
--- @field overlayGradientMesh love.Mesh Общий градиент поверх элемента (интерполированный меш)
|
||
local uiElement = {}
|
||
uiElement.bounds = Rect {}
|
||
uiElement.overlayGradientMesh = makeGradientMesh(1, 1, { 0, 0, 0, 0 }, { 0, 0, 0, 0.4 });
|
||
uiElement.__index = uiElement
|
||
|
||
function uiElement:update(dt) end
|
||
|
||
function uiElement:draw() end
|
||
|
||
function uiElement:hitTest(screenX, screenY)
|
||
return self.bounds:hasPoint(screenX, screenY)
|
||
end
|
||
|
||
--- @generic T : UIElement
|
||
--- @param values table
|
||
--- @param self T
|
||
--- @return T
|
||
function uiElement.new(self, values)
|
||
values.bounds = values.bounds or Rect {}
|
||
values.overlayGradientMesh = values.overlayGradientMesh or uiElement.overlayGradientMesh;
|
||
return setmetatable(values, self)
|
||
end
|
||
|
||
--- Рисует границу вокруг элемента (с псевдо-затенением)
|
||
--- @param type "outer" | "inner"
|
||
--- @param width? number
|
||
function uiElement:drawBorder(type, width)
|
||
love.graphics.setLineWidth(width or 4)
|
||
|
||
if type == "inner" then
|
||
love.graphics.setColor(0.2, 0.2, 0.2)
|
||
love.graphics.line({
|
||
self.bounds.x, self.bounds.y + self.bounds.height,
|
||
self.bounds.x, self.bounds.y,
|
||
self.bounds.x + self.bounds.width, self.bounds.y,
|
||
})
|
||
|
||
love.graphics.setColor(0.3, 0.3, 0.3)
|
||
love.graphics.line({
|
||
self.bounds.x + self.bounds.width, self.bounds.y,
|
||
self.bounds.x + self.bounds.width, self.bounds.y + self.bounds.height,
|
||
self.bounds.x, self.bounds.y + self.bounds.height,
|
||
})
|
||
else
|
||
love.graphics.setColor(0.2, 0.2, 0.2)
|
||
love.graphics.line({
|
||
self.bounds.x + self.bounds.width, self.bounds.y,
|
||
self.bounds.x + self.bounds.width, self.bounds.y + self.bounds.height,
|
||
self.bounds.x, self.bounds.y + self.bounds.height,
|
||
})
|
||
|
||
love.graphics.setColor(0.3, 0.3, 0.3)
|
||
love.graphics.line({
|
||
self.bounds.x, self.bounds.y + self.bounds.height,
|
||
self.bounds.x, self.bounds.y,
|
||
self.bounds.x + self.bounds.width, self.bounds.y,
|
||
})
|
||
end
|
||
|
||
love.graphics.setColor(1, 1, 1)
|
||
end
|
||
|
||
--- рисует градиент поверх элемента
|
||
function uiElement:drawGradientOverlay()
|
||
love.graphics.push()
|
||
love.graphics.translate(self.bounds.x, self.bounds.y)
|
||
love.graphics.scale(self.bounds.width, self.bounds.height)
|
||
love.graphics.setColor(1, 1, 1, 1)
|
||
love.graphics.draw(self.overlayGradientMesh)
|
||
love.graphics.pop()
|
||
end
|
||
|
||
return uiElement
|