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:
|
with:
|
||||||
ref: gh-pages
|
ref: gh-pages
|
||||||
path: build_docs
|
path: build_docs
|
||||||
- name: Prepare content directory
|
- name: Prepare references directory
|
||||||
run: |
|
run: |
|
||||||
mkdir -p build_docs/docs
|
mkdir -p build_docs/docs
|
||||||
rm -rf build_docs/docs/content
|
rm -rf build_docs/docs/references
|
||||||
mkdir -p build_docs/docs/content
|
mkdir -p build_docs/docs/references
|
||||||
- name: Process markdown files
|
- name: Process markdown files
|
||||||
run: |
|
run: |
|
||||||
find src -type f -name "*.lua" | while read file; do
|
find src -type f -name "*.lua" | while read file; do
|
||||||
filename=$(basename "$file")
|
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
|
done
|
||||||
- name: Deploy
|
- name: Deploy
|
||||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
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 = {
|
local commentTypes = {
|
||||||
"module",
|
"module",
|
||||||
|
"class",
|
||||||
"param",
|
"param",
|
||||||
"return",
|
"return",
|
||||||
"usage",
|
"usage",
|
||||||
@@ -79,7 +80,11 @@ function markdown.parse(content)
|
|||||||
if(commentType == "module")then
|
if(commentType == "module")then
|
||||||
currentBlock.usageIsActive = false
|
currentBlock.usageIsActive = false
|
||||||
currentBlock.type = "module"
|
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
|
end
|
||||||
if(commentType == "usage")then
|
if(commentType == "usage")then
|
||||||
currentBlock.usage = currentBlock.usage or {}
|
currentBlock.usage = currentBlock.usage or {}
|
||||||
@@ -205,7 +210,7 @@ local function markdownEvents()
|
|||||||
end
|
end
|
||||||
local output = "\n## Events\n\n"
|
local output = "\n## Events\n\n"
|
||||||
for _, block in pairs(markdown.blocks) do
|
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
|
if(block.event~=nil)then
|
||||||
for _, line in pairs(block.event) do
|
for _, line in pairs(block.event) do
|
||||||
output = output .. "* " .. line .. "\n"
|
output = output .. "* " .. line .. "\n"
|
||||||
@@ -216,7 +221,7 @@ local function markdownEvents()
|
|||||||
return output
|
return output
|
||||||
end
|
end
|
||||||
|
|
||||||
local function markdownModuleFunctions()
|
local function markdownModuleOrClassFunctions()
|
||||||
if(#markdown.blocks<=0)then
|
if(#markdown.blocks<=0)then
|
||||||
return ""
|
return ""
|
||||||
end
|
end
|
||||||
@@ -260,7 +265,32 @@ local function markdownModule(block)
|
|||||||
|
|
||||||
output = output .. markdownProperties()
|
output = output .. markdownProperties()
|
||||||
output = output .. markdownEvents()
|
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"
|
output = output .. "\n"
|
||||||
return output
|
return output
|
||||||
end
|
end
|
||||||
@@ -276,6 +306,8 @@ function markdown.makeMarkdown()
|
|||||||
end
|
end
|
||||||
elseif block.type == "module" then
|
elseif block.type == "module" then
|
||||||
output = output .. markdownModule(block)
|
output = output .. markdownModule(block)
|
||||||
|
elseif block.type == "class" then
|
||||||
|
output = output .. markdownClass(block)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
local PropertySystem = require("propertySystem")
|
local PropertySystem = require("propertySystem")
|
||||||
|
|
||||||
--- The base class for all UI elements in Basalt
|
--- The base class for all UI elements in Basalt
|
||||||
-- @module BaseElement
|
--- @class BaseElement : PropertySystem
|
||||||
local BaseElement = setmetatable({}, PropertySystem)
|
local BaseElement = setmetatable({}, PropertySystem)
|
||||||
BaseElement.__index = BaseElement
|
BaseElement.__index = BaseElement
|
||||||
BaseElement._events = {}
|
BaseElement._events = {}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
local Container = require("elements/Container")
|
local Container = require("elements/Container")
|
||||||
local Render = require("render")
|
local Render = require("render")
|
||||||
|
|
||||||
|
---@class BaseFrame : Container
|
||||||
local BaseFrame = setmetatable({}, Container)
|
local BaseFrame = setmetatable({}, Container)
|
||||||
BaseFrame.__index = BaseFrame
|
BaseFrame.__index = BaseFrame
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
local VisualElement = require("elements/VisualElement")
|
local VisualElement = require("elements/VisualElement")
|
||||||
local getCenteredPosition = require("libraries/utils").getCenteredPosition
|
local getCenteredPosition = require("libraries/utils").getCenteredPosition
|
||||||
|
|
||||||
|
---@class Button : VisualElement
|
||||||
local Button = setmetatable({}, VisualElement)
|
local Button = setmetatable({}, VisualElement)
|
||||||
Button.__index = Button
|
Button.__index = Button
|
||||||
|
|
||||||
Button.defineProperty(Button, "text", {default = "Button", type = "string"})
|
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")
|
Button.listenTo(Button, "mouse_click")
|
||||||
|
|
||||||
---@diagnostic disable-next-line: duplicate-set-field
|
---@diagnostic disable-next-line: duplicate-set-field
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ local expect = require("libraries/expect")
|
|||||||
|
|
||||||
local max = math.max
|
local max = math.max
|
||||||
|
|
||||||
|
---@class Container : VisualElement
|
||||||
local Container = setmetatable({}, VisualElement)
|
local Container = setmetatable({}, VisualElement)
|
||||||
Container.__index = Container
|
Container.__index = Container
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
local Container = require("elements/Container")
|
local Container = require("elements/Container")
|
||||||
|
|
||||||
|
---@class Frame : Container
|
||||||
local Frame = setmetatable({}, Container)
|
local Frame = setmetatable({}, Container)
|
||||||
Frame.__index = Frame
|
Frame.__index = Frame
|
||||||
|
|
||||||
---@diagnostic disable-next-line: duplicate-set-field
|
|
||||||
function Frame.new(id, basalt)
|
function Frame.new(id, basalt)
|
||||||
local self = setmetatable({}, Frame):__init()
|
local self = setmetatable({}, Frame):__init()
|
||||||
self:init(id, basalt)
|
self:init(id, basalt)
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
local BaseElement = require("elements/BaseElement")
|
local BaseElement = require("elements/BaseElement")
|
||||||
|
|
||||||
|
---@alias color number
|
||||||
|
|
||||||
|
---@class VisualElement : BaseElement
|
||||||
local VisualElement = setmetatable({}, BaseElement)
|
local VisualElement = setmetatable({}, BaseElement)
|
||||||
VisualElement.__index = VisualElement
|
VisualElement.__index = VisualElement
|
||||||
local tHex = require("libraries/colorHex")
|
local tHex = require("libraries/colorHex")
|
||||||
|
|
||||||
|
---@property x number 1 x position of the element
|
||||||
BaseElement.defineProperty(VisualElement, "x", {default = 1, type = "number", canTriggerRender = true})
|
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})
|
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)
|
BaseElement.defineProperty(VisualElement, "z", {default = 1, type = "number", canTriggerRender = true, setter = function(self, value)
|
||||||
self.basalt.LOGGER.debug("Setting z to " .. value)
|
self.basalt.LOGGER.debug("Setting z to " .. value)
|
||||||
if self.parent then
|
if self.parent then
|
||||||
@@ -12,13 +19,22 @@ BaseElement.defineProperty(VisualElement, "z", {default = 1, type = "number", ca
|
|||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end})
|
end})
|
||||||
|
---@property width number 1 width of the element
|
||||||
BaseElement.defineProperty(VisualElement, "width", {default = 1, type = "number", canTriggerRender = true})
|
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})
|
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})
|
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})
|
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"})
|
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)
|
function VisualElement.new(id, basalt)
|
||||||
local self = setmetatable({}, VisualElement):__init()
|
local self = setmetatable({}, VisualElement):__init()
|
||||||
self:init(id, basalt)
|
self:init(id, basalt)
|
||||||
@@ -26,18 +42,35 @@ function VisualElement.new(id, basalt)
|
|||||||
return self
|
return self
|
||||||
end
|
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)
|
function VisualElement:multiBlit(x, y, width, height, text, fg, bg)
|
||||||
x = x + self.get("x") - 1
|
x = x + self.get("x") - 1
|
||||||
y = y + self.get("y") - 1
|
y = y + self.get("y") - 1
|
||||||
self.parent:multiBlit(x, y, width, height, text, fg, bg)
|
self.parent:multiBlit(x, y, width, height, text, fg, bg)
|
||||||
end
|
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)
|
function VisualElement:textFg(x, y, text, fg)
|
||||||
x = x + self.get("x") - 1
|
x = x + self.get("x") - 1
|
||||||
y = y + self.get("y") - 1
|
y = y + self.get("y") - 1
|
||||||
self.parent:textFg(x, y, text, fg)
|
self.parent:textFg(x, y, text, fg)
|
||||||
end
|
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)
|
function VisualElement:isInBounds(x, y)
|
||||||
local xPos, yPos = self.get("x"), self.get("y")
|
local xPos, yPos = self.get("x"), self.get("y")
|
||||||
local width, height = self.get("width"), self.get("height")
|
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
|
y >= yPos and y <= yPos + height - 1
|
||||||
end
|
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)
|
function VisualElement:mouse_click(button, x, y)
|
||||||
if self:isInBounds(x, y) then
|
if self:isInBounds(x, y) then
|
||||||
self.set("clicked", true)
|
self.set("clicked", true)
|
||||||
@@ -74,8 +112,8 @@ function VisualElement:handleEvent(event, ...)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Returns the absolute position of the element or the given coordinates.
|
--- Returns the absolute position of the element or the given coordinates.
|
||||||
---@param x? number -- x position
|
---@param x? number x position
|
||||||
---@param y? number -- y position
|
---@param y? number y position
|
||||||
function VisualElement:getAbsolutePosition(x, y)
|
function VisualElement:getAbsolutePosition(x, y)
|
||||||
if (x == nil) or (y == nil) then
|
if (x == nil) or (y == nil) then
|
||||||
x, y = self.get("x"), self.get("y")
|
x, y = self.get("x"), self.get("y")
|
||||||
@@ -93,8 +131,8 @@ function VisualElement:getAbsolutePosition(x, y)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Returns the relative position of the element or the given coordinates.
|
--- Returns the relative position of the element or the given coordinates.
|
||||||
---@param x? number -- x position
|
---@param x? number x position
|
||||||
---@param y? number -- y position
|
---@param y? number y position
|
||||||
---@return number, number
|
---@return number, number
|
||||||
function VisualElement:getRelativePosition(x, y)
|
function VisualElement:getRelativePosition(x, y)
|
||||||
if (x == nil) or (y == nil) then
|
if (x == nil) or (y == nil) then
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ function basalt.stop()
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Starts the Basalt runtime
|
--- 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()
|
||||||
--- @usage basalt.run(false)
|
--- @usage basalt.run(false)
|
||||||
function basalt.run(isActive)
|
function basalt.run(isActive)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
local deepCopy = require("libraries/utils").deepCopy
|
local deepCopy = require("libraries/utils").deepCopy
|
||||||
local expect = require("libraries/expect")
|
local expect = require("libraries/expect")
|
||||||
|
|
||||||
|
--- @class PropertySystem
|
||||||
local PropertySystem = {}
|
local PropertySystem = {}
|
||||||
PropertySystem.__index = PropertySystem
|
PropertySystem.__index = PropertySystem
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user