LuaLS Test
This commit is contained in:
8
.github/workflows/docs.yml
vendored
8
.github/workflows/docs.yml
vendored
@@ -26,16 +26,16 @@ jobs:
|
||||
with:
|
||||
ref: gh-pages
|
||||
path: build_docs
|
||||
- name: Prepare content directory
|
||||
- name: Prepare references directory
|
||||
run: |
|
||||
mkdir -p build_docs/docs
|
||||
rm -rf build_docs/docs/content
|
||||
mkdir -p build_docs/docs/content
|
||||
rm -rf build_docs/docs/references
|
||||
mkdir -p build_docs/docs/references
|
||||
- name: Process markdown files
|
||||
run: |
|
||||
find src -type f -name "*.lua" | while read file; do
|
||||
filename=$(basename "$file")
|
||||
lua markdown.lua "$file" "build_docs/docs/content/${filename%.lua}.md"
|
||||
lua markdown.lua "$file" "build_docs/docs/references/${filename%.lua}.md"
|
||||
done
|
||||
- name: Deploy
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
||||
|
||||
36
.github/workflows/lualsgen.yml
vendored
Normal file
36
.github/workflows/lualsgen.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
name: Generate LuaLS Definitions
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'src/elements/**'
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
paths:
|
||||
- 'src/elements/**'
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
generate:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Lua
|
||||
uses: leafo/gh-actions-lua@v8
|
||||
with:
|
||||
luaVersion: "5.4"
|
||||
|
||||
- name: Generate LuaLS definitions
|
||||
run: |
|
||||
lua annotationParser.lua src/elements src/LuaLS.lua
|
||||
|
||||
- name: Commit changes
|
||||
if: github.event_name == 'push'
|
||||
run: |
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "GitHub Action"
|
||||
git add src/LuaLS.lua
|
||||
git commit -m "Update LuaLS definitions" || true
|
||||
git push
|
||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
test.lua
|
||||
203
LuaLS.lua
Normal file
203
LuaLS.lua
Normal file
@@ -0,0 +1,203 @@
|
||||
---@class Button
|
||||
local Button = {}
|
||||
|
||||
--- The event that is triggered when the button is clicked
|
||||
---@generic Element: Button
|
||||
---@param self Element
|
||||
---@param callback function
|
||||
---@return Element
|
||||
function Button:onMouseClick(callback)
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
---@class Container
|
||||
local Container = {}
|
||||
|
||||
--- Adds a new Button to the container
|
||||
---@generic Element: Container
|
||||
---@param self Element
|
||||
---@return Button
|
||||
function Container:addButton()
|
||||
return self
|
||||
end
|
||||
|
||||
--- Adds a new Container to the container
|
||||
---@generic Element: Container
|
||||
---@param self Element
|
||||
---@return Container
|
||||
function Container:addContainer()
|
||||
return self
|
||||
end
|
||||
|
||||
--- Adds a new Frame to the container
|
||||
---@generic Element: Container
|
||||
---@param self Element
|
||||
---@return Frame
|
||||
function Container:addFrame()
|
||||
return self
|
||||
end
|
||||
|
||||
--- Adds a new VisualElement to the container
|
||||
---@generic Element: Container
|
||||
---@param self Element
|
||||
---@return VisualElement
|
||||
function Container:addVisualElement()
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
---@class VisualElement
|
||||
---@field x number
|
||||
---@field y number
|
||||
---@field z number
|
||||
---@field width number
|
||||
---@field height number
|
||||
---@field background color
|
||||
---@field foreground color
|
||||
---@field clicked boolean
|
||||
local VisualElement = {}
|
||||
|
||||
--- Gets the x position of the element
|
||||
---@generic Element: VisualElement
|
||||
---@param self Element
|
||||
---@return number
|
||||
function VisualElement:getX()
|
||||
return self.x
|
||||
end
|
||||
|
||||
--- Sets the x position of the element
|
||||
---@generic Element: VisualElement
|
||||
---@param self Element
|
||||
---@param x number
|
||||
---@return Element
|
||||
function VisualElement:setX(x)
|
||||
self.x = x
|
||||
return self
|
||||
end
|
||||
|
||||
--- Gets the y position of the element
|
||||
---@generic Element: VisualElement
|
||||
---@param self Element
|
||||
---@return number
|
||||
function VisualElement:getY()
|
||||
return self.y
|
||||
end
|
||||
|
||||
--- Sets the y position of the element
|
||||
---@generic Element: VisualElement
|
||||
---@param self Element
|
||||
---@param y number
|
||||
---@return Element
|
||||
function VisualElement:setY(y)
|
||||
self.y = y
|
||||
return self
|
||||
end
|
||||
|
||||
--- Gets the z position of the element
|
||||
---@generic Element: VisualElement
|
||||
---@param self Element
|
||||
---@return number
|
||||
function VisualElement:getZ()
|
||||
return self.z
|
||||
end
|
||||
|
||||
--- Sets the z position of the element
|
||||
---@generic Element: VisualElement
|
||||
---@param self Element
|
||||
---@param z number
|
||||
---@return Element
|
||||
function VisualElement:setZ(z)
|
||||
self.z = z
|
||||
return self
|
||||
end
|
||||
|
||||
--- Gets the width of the element
|
||||
---@generic Element: VisualElement
|
||||
---@param self Element
|
||||
---@return number
|
||||
function VisualElement:getWidth()
|
||||
return self.width
|
||||
end
|
||||
|
||||
--- Sets the width of the element
|
||||
---@generic Element: VisualElement
|
||||
---@param self Element
|
||||
---@param width number
|
||||
---@return Element
|
||||
function VisualElement:setWidth(width)
|
||||
self.width = width
|
||||
return self
|
||||
end
|
||||
|
||||
--- Gets the height of the element
|
||||
---@generic Element: VisualElement
|
||||
---@param self Element
|
||||
---@return number
|
||||
function VisualElement:getHeight()
|
||||
return self.height
|
||||
end
|
||||
|
||||
--- Sets the height of the element
|
||||
---@generic Element: VisualElement
|
||||
---@param self Element
|
||||
---@param height number
|
||||
---@return Element
|
||||
function VisualElement:setHeight(height)
|
||||
self.height = height
|
||||
return self
|
||||
end
|
||||
|
||||
--- Gets the background color of the element
|
||||
---@generic Element: VisualElement
|
||||
---@param self Element
|
||||
---@return color
|
||||
function VisualElement:getBackground()
|
||||
return self.background
|
||||
end
|
||||
|
||||
--- Sets the background color of the element
|
||||
---@generic Element: VisualElement
|
||||
---@param self Element
|
||||
---@param background color
|
||||
---@return Element
|
||||
function VisualElement:setBackground(background)
|
||||
self.background = background
|
||||
return self
|
||||
end
|
||||
|
||||
--- Gets the foreground color of the element
|
||||
---@generic Element: VisualElement
|
||||
---@param self Element
|
||||
---@return color
|
||||
function VisualElement:getForeground()
|
||||
return self.foreground
|
||||
end
|
||||
|
||||
--- Sets the foreground color of the element
|
||||
---@generic Element: VisualElement
|
||||
---@param self Element
|
||||
---@param foreground color
|
||||
---@return Element
|
||||
function VisualElement:setForeground(foreground)
|
||||
self.foreground = foreground
|
||||
return self
|
||||
end
|
||||
|
||||
--- Gets the element is currently clicked
|
||||
---@generic Element: VisualElement
|
||||
---@param self Element
|
||||
---@return boolean
|
||||
function VisualElement:getClicked()
|
||||
return self.clicked
|
||||
end
|
||||
|
||||
--- Sets the element is currently clicked
|
||||
---@generic Element: VisualElement
|
||||
---@param self Element
|
||||
---@param clicked boolean
|
||||
---@return Element
|
||||
function VisualElement:setClicked(clicked)
|
||||
self.clicked = clicked
|
||||
return self
|
||||
end
|
||||
226
annotationParser.lua
Normal file
226
annotationParser.lua
Normal file
@@ -0,0 +1,226 @@
|
||||
local function parseProperty(line)
|
||||
-- Matches: ---@property name type default description
|
||||
local name, type, default, description = line:match("%-%-%-@property%s+(%w+)%s+(%w+)%s+(.-)%s+(.*)")
|
||||
|
||||
if name and type then
|
||||
-- Generate field annotation
|
||||
local fieldDef = string.format("---@field %s %s\n", name, type)
|
||||
|
||||
-- Generate getter annotation and function
|
||||
local getterDoc = string.format([[
|
||||
--- Gets the %s
|
||||
---@generic T: %s
|
||||
---@param self T
|
||||
---@return %s
|
||||
]], description, "VisualElement", type)
|
||||
|
||||
local getterFunc = string.format([[
|
||||
function VisualElement:get%s()
|
||||
return self.%s
|
||||
end
|
||||
]], name:sub(1,1):upper() .. name:sub(2), name)
|
||||
|
||||
-- Generate setter annotation and function
|
||||
local setterDoc = string.format([[
|
||||
--- Sets the %s
|
||||
---@generic T: %s
|
||||
---@param self T
|
||||
---@param %s %s
|
||||
---@return T
|
||||
]], description, "VisualElement", name, type)
|
||||
|
||||
local setterFunc = string.format([[
|
||||
function VisualElement:set%s(%s)
|
||||
self.%s = %s
|
||||
return self
|
||||
end
|
||||
]], name:sub(1,1):upper() .. name:sub(2), name, name, name)
|
||||
|
||||
return fieldDef .. getterDoc .. getterFunc .. setterDoc .. setterFunc
|
||||
end
|
||||
end
|
||||
|
||||
local input = [[
|
||||
---@property x number 1 The x position of the element
|
||||
---@property y number 1 The y position of the element
|
||||
]]
|
||||
|
||||
for line in input:gmatch("[^\r\n]+") do
|
||||
parseProperty(line)
|
||||
end
|
||||
|
||||
local function findClassName(content)
|
||||
return content:match("%-%-%-@class%s+(%w+)")
|
||||
end
|
||||
|
||||
local function parseProperties(content)
|
||||
local properties = {}
|
||||
for line in content:gmatch("[^\r\n]+") do
|
||||
local name, type, default, desc = line:match("%-%-%-@property%s+(%w+)%s+(%w+)%s+(.-)%s+(.*)")
|
||||
if name and type then
|
||||
properties[#properties + 1] = {
|
||||
name = name,
|
||||
type = type,
|
||||
default = default,
|
||||
description = desc
|
||||
}
|
||||
end
|
||||
end
|
||||
return properties
|
||||
end
|
||||
|
||||
local function parseEvents(content)
|
||||
local events = {}
|
||||
for line in content:gmatch("[^\r\n]+") do
|
||||
|
||||
local name, description = line:match("%-%-%-@event%s+([%w_]+)%s+(.+)")
|
||||
if name then
|
||||
local functionName = name:gsub("_(%w)", function(c) return c:upper() end)
|
||||
functionName = "on" .. functionName:sub(1,1):upper() .. functionName:sub(2)
|
||||
|
||||
events[#events + 1] = {
|
||||
name = name,
|
||||
functionName = functionName,
|
||||
description = description
|
||||
}
|
||||
end
|
||||
end
|
||||
return events
|
||||
end
|
||||
|
||||
local function collectAllClassNames(folder)
|
||||
local classes = {}
|
||||
local files = fs.list(folder)
|
||||
|
||||
for _, filename in ipairs(files) do
|
||||
if filename:match("%.lua$") then
|
||||
local path = fs.combine(folder, filename)
|
||||
local f = fs.open(path, "r")
|
||||
if f then
|
||||
local content = f.readAll()
|
||||
f.close()
|
||||
|
||||
local className = findClassName(content)
|
||||
if className and className ~= "BaseFrame" then
|
||||
table.insert(classes, className)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return classes
|
||||
end
|
||||
|
||||
local function generateClassContent(className, properties, events, allClasses)
|
||||
if #properties == 0 and #events == 0 and className ~= "Container" then
|
||||
return nil
|
||||
end
|
||||
|
||||
local content = {}
|
||||
table.insert(content, string.format("---@class %s", className))
|
||||
|
||||
for _, prop in ipairs(properties) do
|
||||
table.insert(content, string.format("---@field %s %s", prop.name, prop.type))
|
||||
end
|
||||
|
||||
table.insert(content, string.format("local %s = {}", className))
|
||||
table.insert(content, "")
|
||||
|
||||
for _, prop in ipairs(properties) do
|
||||
table.insert(content, string.format("--- Gets the %s", prop.description))
|
||||
table.insert(content, string.format("---@generic Element: %s", className))
|
||||
table.insert(content, "---@param self Element")
|
||||
table.insert(content, string.format("---@return %s", prop.type))
|
||||
table.insert(content, string.format("function %s:get%s()",
|
||||
className,
|
||||
prop.name:sub(1,1):upper() .. prop.name:sub(2)
|
||||
))
|
||||
table.insert(content, string.format(" return self.%s", prop.name))
|
||||
table.insert(content, "end")
|
||||
table.insert(content, "")
|
||||
|
||||
table.insert(content, string.format("--- Sets the %s", prop.description))
|
||||
table.insert(content, string.format("---@generic Element: %s", className))
|
||||
table.insert(content, "---@param self Element")
|
||||
table.insert(content, string.format("---@param %s %s", prop.name, prop.type))
|
||||
table.insert(content, "---@return Element")
|
||||
table.insert(content, string.format("function %s:set%s(%s)",
|
||||
className,
|
||||
prop.name:sub(1,1):upper() .. prop.name:sub(2),
|
||||
prop.name
|
||||
))
|
||||
table.insert(content, string.format(" self.%s = %s", prop.name, prop.name))
|
||||
table.insert(content, " return self")
|
||||
table.insert(content, "end")
|
||||
table.insert(content, "")
|
||||
end
|
||||
|
||||
for _, event in ipairs(events) do
|
||||
table.insert(content, string.format([[
|
||||
--- %s
|
||||
---@generic Element: %s
|
||||
---@param self Element
|
||||
---@param callback function
|
||||
---@return Element
|
||||
function %s:%s(callback)
|
||||
return self
|
||||
end]], event.description, className, className, event.functionName))
|
||||
table.insert(content, "")
|
||||
end
|
||||
|
||||
if className == "Container" then
|
||||
for _, cls in ipairs(allClasses) do
|
||||
table.insert(content, string.format([[
|
||||
--- Adds a new %s to the container
|
||||
---@generic Element: Container
|
||||
---@param self Element
|
||||
---@return %s
|
||||
function Container:add%s()
|
||||
return self
|
||||
end]], cls, cls, cls))
|
||||
table.insert(content, "")
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(content, "\n")
|
||||
end
|
||||
|
||||
local function parseFolder(folder, destinationFile)
|
||||
local allClasses = collectAllClassNames(folder)
|
||||
local allContent = {}
|
||||
|
||||
local files = fs.list(folder)
|
||||
|
||||
for _, filename in ipairs(files) do
|
||||
if filename:match("%.lua$") then
|
||||
local path = fs.combine(folder, filename)
|
||||
local f = fs.open(path, "r")
|
||||
if f then
|
||||
local content = f.readAll()
|
||||
f.close()
|
||||
|
||||
local className = findClassName(content)
|
||||
if className then
|
||||
local properties = parseProperties(content)
|
||||
local events = parseEvents(content)
|
||||
local classContent = generateClassContent(className, properties, events, allClasses)
|
||||
if classContent then -- Only add if content was generated
|
||||
table.insert(allContent, classContent)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local f = fs.open(destinationFile, "w")
|
||||
if f then
|
||||
f.write(table.concat(allContent, "\n\n"))
|
||||
f.close()
|
||||
end
|
||||
end
|
||||
|
||||
local args = {...}
|
||||
if #args == 2 then
|
||||
parseFolder(args[1], args[2])
|
||||
else
|
||||
print("Usage: annotationParser <sourceFolder> <destinationFile>")
|
||||
end
|
||||
31
example.lua
Normal file
31
example.lua
Normal file
@@ -0,0 +1,31 @@
|
||||
---@generic Element: Animal
|
||||
---@class Animal
|
||||
---@field setName fun(self: Element, name: string): Element
|
||||
local Animal = {}
|
||||
|
||||
---@class Dog : Animal
|
||||
---@field setSpeed fun(self: Dog, speed: number): Dog
|
||||
local Dog = setmetatable({}, { __index = Animal })
|
||||
|
||||
---@generic Element: Animal
|
||||
---@param self Element
|
||||
---@param length string
|
||||
---@return Element
|
||||
function Animal:setLength(length)
|
||||
self.length = length
|
||||
return self
|
||||
end
|
||||
|
||||
function Dog:setSpeed(speed)
|
||||
self.speed = speed
|
||||
return self
|
||||
end
|
||||
|
||||
---@return Dog
|
||||
function Dog.new()
|
||||
return setmetatable({}, { __index = Dog })
|
||||
end
|
||||
|
||||
local dog = Dog.new()
|
||||
dog:setName("Rex")
|
||||
:setSpeed(10)
|
||||
40
markdown.lua
40
markdown.lua
@@ -4,6 +4,7 @@ local markdown = {
|
||||
|
||||
local commentTypes = {
|
||||
"module",
|
||||
"class",
|
||||
"param",
|
||||
"return",
|
||||
"usage",
|
||||
@@ -79,7 +80,11 @@ function markdown.parse(content)
|
||||
if(commentType == "module")then
|
||||
currentBlock.usageIsActive = false
|
||||
currentBlock.type = "module"
|
||||
currentBlock.moduleName = value
|
||||
currentBlock.moduleName = value:match("([^%s]+)")
|
||||
elseif(commentType == "class")then
|
||||
currentBlock.usageIsActive = false
|
||||
currentBlock.type = "class"
|
||||
currentBlock.className = value
|
||||
end
|
||||
if(commentType == "usage")then
|
||||
currentBlock.usage = currentBlock.usage or {}
|
||||
@@ -205,7 +210,7 @@ local function markdownEvents()
|
||||
end
|
||||
local output = "\n## Events\n\n"
|
||||
for _, block in pairs(markdown.blocks) do
|
||||
if block.type == "module" then
|
||||
if block.type == "module" or block.type == "class" then
|
||||
if(block.event~=nil)then
|
||||
for _, line in pairs(block.event) do
|
||||
output = output .. "* " .. line .. "\n"
|
||||
@@ -216,7 +221,7 @@ local function markdownEvents()
|
||||
return output
|
||||
end
|
||||
|
||||
local function markdownModuleFunctions()
|
||||
local function markdownModuleOrClassFunctions()
|
||||
if(#markdown.blocks<=0)then
|
||||
return ""
|
||||
end
|
||||
@@ -260,7 +265,32 @@ local function markdownModule(block)
|
||||
|
||||
output = output .. markdownProperties()
|
||||
output = output .. markdownEvents()
|
||||
output = output .. markdownModuleFunctions(block)
|
||||
output = output .. markdownModuleOrClassFunctions(block)
|
||||
output = output .. "\n"
|
||||
return output
|
||||
end
|
||||
|
||||
local function markdownClass(block)
|
||||
local output = "# ".. block.className.."\n"
|
||||
if(block.usage~=nil)then
|
||||
if(#block.usage > 0)then
|
||||
for k,v in pairs(block.usage) do
|
||||
local _output = "\n### Usage\n ```lua\n"
|
||||
for _, line in pairs(v.content) do
|
||||
_output = _output .. line .. "\n"
|
||||
end
|
||||
_output = _output .. "```\n"
|
||||
table.insert(block.desc, v.line, _output)
|
||||
end
|
||||
end
|
||||
end
|
||||
for _, line in pairs(block.desc) do
|
||||
output = output .. line .. "\n"
|
||||
end
|
||||
|
||||
output = output .. markdownProperties()
|
||||
output = output .. markdownEvents()
|
||||
output = output .. markdownModuleOrClassFunctions(block)
|
||||
output = output .. "\n"
|
||||
return output
|
||||
end
|
||||
@@ -276,6 +306,8 @@ function markdown.makeMarkdown()
|
||||
end
|
||||
elseif block.type == "module" then
|
||||
output = output .. markdownModule(block)
|
||||
elseif block.type == "class" then
|
||||
output = output .. markdownClass(block)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
local PropertySystem = require("propertySystem")
|
||||
|
||||
--- The base class for all UI elements in Basalt
|
||||
-- @module BaseElement
|
||||
--- @class BaseElement : PropertySystem
|
||||
local BaseElement = setmetatable({}, PropertySystem)
|
||||
BaseElement.__index = BaseElement
|
||||
BaseElement._events = {}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
local Container = require("elements/Container")
|
||||
local Render = require("render")
|
||||
|
||||
---@class BaseFrame : Container
|
||||
local BaseFrame = setmetatable({}, Container)
|
||||
BaseFrame.__index = BaseFrame
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
local VisualElement = require("elements/VisualElement")
|
||||
local getCenteredPosition = require("libraries/utils").getCenteredPosition
|
||||
|
||||
---@class Button : VisualElement
|
||||
local Button = setmetatable({}, VisualElement)
|
||||
Button.__index = Button
|
||||
|
||||
Button.defineProperty(Button, "text", {default = "Button", type = "string"})
|
||||
|
||||
---@event mouse_click The event that is triggered when the button is clicked
|
||||
Button.listenTo(Button, "mouse_click")
|
||||
|
||||
---@diagnostic disable-next-line: duplicate-set-field
|
||||
|
||||
@@ -4,6 +4,7 @@ local expect = require("libraries/expect")
|
||||
|
||||
local max = math.max
|
||||
|
||||
---@class Container : VisualElement
|
||||
local Container = setmetatable({}, VisualElement)
|
||||
Container.__index = Container
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
local Container = require("elements/Container")
|
||||
|
||||
---@class Frame : Container
|
||||
local Frame = setmetatable({}, Container)
|
||||
Frame.__index = Frame
|
||||
|
||||
---@diagnostic disable-next-line: duplicate-set-field
|
||||
function Frame.new(id, basalt)
|
||||
local self = setmetatable({}, Frame):__init()
|
||||
self:init(id, basalt)
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
local BaseElement = require("elements/BaseElement")
|
||||
|
||||
---@alias color number
|
||||
|
||||
---@class VisualElement : BaseElement
|
||||
local VisualElement = setmetatable({}, BaseElement)
|
||||
VisualElement.__index = VisualElement
|
||||
local tHex = require("libraries/colorHex")
|
||||
|
||||
---@property x number 1 x position of the element
|
||||
BaseElement.defineProperty(VisualElement, "x", {default = 1, type = "number", canTriggerRender = true})
|
||||
---@property y number 1 y position of the element
|
||||
BaseElement.defineProperty(VisualElement, "y", {default = 1, type = "number", canTriggerRender = true})
|
||||
---@property z number 1 z position of the element
|
||||
BaseElement.defineProperty(VisualElement, "z", {default = 1, type = "number", canTriggerRender = true, setter = function(self, value)
|
||||
self.basalt.LOGGER.debug("Setting z to " .. value)
|
||||
if self.parent then
|
||||
@@ -12,13 +19,22 @@ BaseElement.defineProperty(VisualElement, "z", {default = 1, type = "number", ca
|
||||
end
|
||||
return value
|
||||
end})
|
||||
---@property width number 1 width of the element
|
||||
BaseElement.defineProperty(VisualElement, "width", {default = 1, type = "number", canTriggerRender = true})
|
||||
---@property height number 1 height of the element
|
||||
BaseElement.defineProperty(VisualElement, "height", {default = 1, type = "number", canTriggerRender = true})
|
||||
---@property background color black background color of the element
|
||||
BaseElement.defineProperty(VisualElement, "background", {default = colors.black, type = "number", canTriggerRender = true})
|
||||
---@property foreground color white foreground color of the element
|
||||
BaseElement.defineProperty(VisualElement, "foreground", {default = colors.white, type = "number", canTriggerRender = true})
|
||||
---@property clicked boolean false element is currently clicked
|
||||
BaseElement.defineProperty(VisualElement, "clicked", {default = false, type = "boolean"})
|
||||
|
||||
---@diagnostic disable-next-line: duplicate-set-field
|
||||
--- Creates a new VisualElement instance
|
||||
--- @param id string The unique identifier for this element
|
||||
--- @param basalt table The basalt instance
|
||||
--- @return VisualElement object The newly created VisualElement instance
|
||||
--- @usage local element = VisualElement.new("myId", basalt)
|
||||
function VisualElement.new(id, basalt)
|
||||
local self = setmetatable({}, VisualElement):__init()
|
||||
self:init(id, basalt)
|
||||
@@ -26,18 +42,35 @@ function VisualElement.new(id, basalt)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Draws a text character/fg/bg at the specified position with a certain size, used in the rendering system
|
||||
--- @param x number The x position to draw
|
||||
--- @param y number The y position to draw
|
||||
--- @param width number The width of the element
|
||||
--- @param height number The height of the element
|
||||
--- @param text string The text char to draw
|
||||
--- @param fg color The foreground color
|
||||
--- @param bg color The background color
|
||||
function VisualElement:multiBlit(x, y, width, height, text, fg, bg)
|
||||
x = x + self.get("x") - 1
|
||||
y = y + self.get("y") - 1
|
||||
self.parent:multiBlit(x, y, width, height, text, fg, bg)
|
||||
end
|
||||
|
||||
--- Draws a text character at the specified position, used in the rendering system
|
||||
--- @param x number The x position to draw
|
||||
--- @param y number The y position to draw
|
||||
--- @param text string The text char to draw
|
||||
--- @param fg color The foreground color
|
||||
function VisualElement:textFg(x, y, text, fg)
|
||||
x = x + self.get("x") - 1
|
||||
y = y + self.get("y") - 1
|
||||
self.parent:textFg(x, y, text, fg)
|
||||
end
|
||||
|
||||
--- Checks if the specified coordinates are within the bounds of the element
|
||||
--- @param x number The x position to check
|
||||
--- @param y number The y position to check
|
||||
--- @return boolean isInBounds Whether the coordinates are within the bounds of the element
|
||||
function VisualElement:isInBounds(x, y)
|
||||
local xPos, yPos = self.get("x"), self.get("y")
|
||||
local width, height = self.get("width"), self.get("height")
|
||||
@@ -46,6 +79,11 @@ function VisualElement:isInBounds(x, y)
|
||||
y >= yPos and y <= yPos + height - 1
|
||||
end
|
||||
|
||||
--- Handles a mouse click event
|
||||
--- @param button number The button that was clicked
|
||||
--- @param x number The x position of the click
|
||||
--- @param y number The y position of the click
|
||||
--- @return boolean clicked Whether the element was clicked
|
||||
function VisualElement:mouse_click(button, x, y)
|
||||
if self:isInBounds(x, y) then
|
||||
self.set("clicked", true)
|
||||
@@ -74,8 +112,8 @@ function VisualElement:handleEvent(event, ...)
|
||||
end
|
||||
|
||||
--- Returns the absolute position of the element or the given coordinates.
|
||||
---@param x? number -- x position
|
||||
---@param y? number -- y position
|
||||
---@param x? number x position
|
||||
---@param y? number y position
|
||||
function VisualElement:getAbsolutePosition(x, y)
|
||||
if (x == nil) or (y == nil) then
|
||||
x, y = self.get("x"), self.get("y")
|
||||
@@ -93,8 +131,8 @@ function VisualElement:getAbsolutePosition(x, y)
|
||||
end
|
||||
|
||||
--- Returns the relative position of the element or the given coordinates.
|
||||
---@param x? number -- x position
|
||||
---@param y? number -- y position
|
||||
---@param x? number x position
|
||||
---@param y? number y position
|
||||
---@return number, number
|
||||
function VisualElement:getRelativePosition(x, y)
|
||||
if (x == nil) or (y == nil) then
|
||||
|
||||
@@ -133,7 +133,7 @@ function basalt.stop()
|
||||
end
|
||||
|
||||
--- Starts the Basalt runtime
|
||||
--- @param isActive boolean Whether to start active (default: true)
|
||||
--- @param isActive? boolean Whether to start active (default: true)
|
||||
--- @usage basalt.run()
|
||||
--- @usage basalt.run(false)
|
||||
function basalt.run(isActive)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
local deepCopy = require("libraries/utils").deepCopy
|
||||
local expect = require("libraries/expect")
|
||||
|
||||
--- @class PropertySystem
|
||||
local PropertySystem = {}
|
||||
PropertySystem.__index = PropertySystem
|
||||
|
||||
|
||||
Reference in New Issue
Block a user