This commit is contained in:
NoryiE
2025-02-16 19:31:38 +00:00
parent dd6825f3b6
commit 056897dd1b
36 changed files with 1085 additions and 5065 deletions

View File

@@ -1,272 +1,183 @@
local elementManager = require("elementManager")
local BaseElement = elementManager.getElement("BaseElement")
local tHex = require("libraries/colorHex")
@alias color number
# VisualElement : BaseElement
---@alias color number
## Properties
---@class VisualElement : BaseElement
local VisualElement = setmetatable({}, BaseElement)
VisualElement.__index = VisualElement
|Property|Type|Default|Description|
|---|---|---|---|
|x|number|1|x position of the element
|y|number|1|y position of the element
|z|number|1|z position of the element
|width|number|1|width of the element
|height|number|1|height of the element
|background|color|black|background color of the element
|foreground|color|white|foreground color of the element
|clicked|boolean|an|false element is currently clicked
|backgroundEnabled|boolean|true|whether the background is enabled
|focused|boolean|false|whether the element is focused
|visible|boolean|true|whether the element is visible
---@property x number 1 x position of the element
VisualElement.defineProperty(VisualElement, "x", {default = 1, type = "number", canTriggerRender = true})
---@property y number 1 y position of the element
VisualElement.defineProperty(VisualElement, "y", {default = 1, type = "number", canTriggerRender = true})
---@property z number 1 z position of the element
VisualElement.defineProperty(VisualElement, "z", {default = 1, type = "number", canTriggerRender = true, setter = function(self, value)
if self.parent then
self.parent:sortChildren()
end
return value
end})
## Functions
---@property width number 1 width of the element
VisualElement.defineProperty(VisualElement, "width", {default = 1, type = "number", canTriggerRender = true})
---@property height number 1 height of the element
VisualElement.defineProperty(VisualElement, "height", {default = 1, type = "number", canTriggerRender = true})
---@property background color black background color of the element
VisualElement.defineProperty(VisualElement, "background", {default = colors.black, type = "number", canTriggerRender = true})
---@property foreground color white foreground color of the element
VisualElement.defineProperty(VisualElement, "foreground", {default = colors.white, type = "number", canTriggerRender = true})
---@property clicked boolean an false element is currently clicked
VisualElement.defineProperty(VisualElement, "clicked", {default = false, type = "boolean"})
---@property backgroundEnabled boolean true whether the background is enabled
VisualElement.defineProperty(VisualElement, "backgroundEnabled", {default = true, type = "boolean", canTriggerRender = true})
---@property focused boolean false whether the element is focused
VisualElement.defineProperty(VisualElement, "focused", {default = false, type = "boolean", setter = function(self, value, internal)
local curValue = self.get("focused")
if value == curValue then return value end
|Method|Returns|Description|
|---|---|---|
|[VisualElement.new](#VisualElement.new)|VisualElement|
|[VisualElement:blit](#VisualElement:blit)|-|
|[VisualElement:blur](#VisualElement:blur)|-|
|[VisualElement:focus](#VisualElement:focus)|-|
|[VisualElement:getAbsolutePosition](#VisualElement:getAbsolutePosition)|-|
|[VisualElement:getRelativePosition](#VisualElement:getRelativePosition)|number,|
|[VisualElement:init](#VisualElement:init)|-|
|[VisualElement:isInBounds](#VisualElement:isInBounds)|boolean|
|[VisualElement:mouse_click](#VisualElement:mouse_click)|boolean|
|[VisualElement:mouse_release](#VisualElement:mouse_release)|boolean|
|[VisualElement:mouse_up](#VisualElement:mouse_up)|boolean|
|[VisualElement:multiBlit](#VisualElement:multiBlit)|-|
|[VisualElement:render](#VisualElement:render)|-|
|[VisualElement:setCursor](#VisualElement:setCursor)|-|
|[VisualElement:textBg](#VisualElement:textBg)|-|
|[VisualElement:textFg](#VisualElement:textFg)|-|
if value then
self:focus()
else
self:blur()
end
@combinedProperty position x y
@combinedProperty size width height
@combinedProperty color foreground background
## VisualElement.new(props, basalt)
Creates a new VisualElement instance
if not internal and self.parent then
if value then
self.parent:setFocusedChild(self)
else
self.parent:setFocusedChild(nil)
end
end
return value
end})
### Parameters
* `props` `table` The properties to initialize the element with
* `basalt` `table` The basalt instance
---@property visible boolean true whether the element is visible
VisualElement.defineProperty(VisualElement, "visible", {default = true, type = "boolean", canTriggerRender = true, setter=function(self, value)
if(self.parent~=nil)then
self.parent.set("childrenSorted", false)
self.parent.set("childrenEventsSorted", false)
end
return value
end})
### Returns
* `VisualElement` `object` The newly created VisualElement instance
---@combinedProperty position x y
VisualElement.combineProperties(VisualElement, "position", "x", "y")
---@combinedProperty size width height
VisualElement.combineProperties(VisualElement, "size", "width", "height")
---@combinedProperty color foreground background
VisualElement.combineProperties(VisualElement, "color", "foreground", "background")
### Usage
```lua
local element = VisualElement.new("myId", basalt)
```
VisualElement.listenTo(VisualElement, "focus")
VisualElement.listenTo(VisualElement, "blur")
## VisualElement:blit(x, y, text, fg, bg)
Draws a text character with a foreground and background at the specified position, used in the rendering system
local max, min = math.max, math.min
### Parameters
* `x` `number` The x position to draw
* `y` `number` The y position to draw
* `text` `string` The text char to draw
* `fg` `string` The foreground color
* `bg` `string` The background color
--- Creates a new VisualElement instance
--- @param props table The properties to initialize the element with
--- @param basalt table The basalt instance
--- @return VisualElement object The newly created VisualElement instance
--- @usage local element = VisualElement.new("myId", basalt)
function VisualElement.new()
local self = setmetatable({}, VisualElement):__init()
return self
end
## VisualElement:blur()
Handles a blur event
--- Initializes the VisualElement instance
function VisualElement:init(props, basalt)
BaseElement.init(self, props, basalt)
self.set("type", "VisualElement")
end
## VisualElement:focus()
Handles a focus event
--- 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
## VisualElement:getAbsolutePosition(x?, y?)
Returns the absolute position of the element or the given coordinates.
--- 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
### Parameters
* `x` *(optional)* `number` x position
* `y` *(optional)* `number` y position
--- Draws a text character with a background 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 bg color The background color
function VisualElement:textBg(x, y, text, bg)
x = x + self.get("x") - 1
y = y + self.get("y") - 1
self.parent:textBg(x, y, text, bg)
end
## VisualElement:getRelativePosition(x?, y?)
Returns the relative position of the element or the given coordinates.
--- Draws a text character with a foreground and background 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 string The foreground color
--- @param bg string The background color
function VisualElement:blit(x, y, text, fg, bg)
x = x + self.get("x") - 1
y = y + self.get("y") - 1
self.parent:blit(x, y, text, fg, bg)
end
### Parameters
* `x` *(optional)* `number` x position
* `y` *(optional)* `number` y position
--- 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")
### Returns
* `nil` `nil` nil
return x >= xPos and x <= xPos + width - 1 and
y >= yPos and y <= yPos + height - 1
end
## VisualElement:init()
Initializes the VisualElement instance
--- 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)
self:fireEvent("mouse_click", button, self:getRelativePosition(x, y))
return true
end
return false
end
## VisualElement:isInBounds(x, y)
Checks if the specified coordinates are within the bounds of the element
--- Handles a mouse up event
--- @param button number The button that was released
--- @param x number The x position of the release
--- @param y number The y position of the release
--- @return boolean release Whether the element was released on the element
function VisualElement:mouse_up(button, x, y)
self.set("clicked", false)
if self:isInBounds(x, y) then
self:fireEvent("mouse_up", button, x, y)
return true
end
self:fireEvent("mouse_release", button, self:getRelativePosition(x, y))
end
### Parameters
* `x` `number` The x position to check
* `y` `number` The y position to check
--- Handles a mouse release event
--- @param button number The button that was released
--- @param x number The x position of the release
--- @param y number The y position of the release
--- @return boolean release Whether the element was released on the element
function VisualElement:mouse_release(button, x, y)
if self.get("clicked") then
self:fireEvent("mouse_release", button, self:getRelativePosition(x, y))
self.set("clicked", false)
return true
end
return false
end
### Returns
* `boolean` `isInBounds` Whether the coordinates are within the bounds of the element
--- Handles a focus event
function VisualElement:focus()
self:fireEvent("focus")
end
## VisualElement:mouse_click(button, x, y)
Handles a mouse click event
--- Handles a blur event
function VisualElement:blur()
self:fireEvent("blur")
self:setCursor(1,1, false)
end
### Parameters
* `button` `number` The button that was clicked
* `x` `number` The x position of the click
* `y` `number` The y position of the click
--- Returns the absolute position of the element or the given coordinates.
---@param x? number x position
---@param y? number y position
function VisualElement:getAbsolutePosition(x, y)
local xPos, yPos = self.get("x"), self.get("y")
if(x ~= nil) then
xPos = xPos + x - 1
end
if(y ~= nil) then
yPos = yPos + y - 1
end
### Returns
* `boolean` `clicked` Whether the element was clicked
local parent = self.parent
while parent do
local px, py = parent.get("x"), parent.get("y")
xPos = xPos + px - 1
yPos = yPos + py - 1
parent = parent.parent
end
## VisualElement:mouse_release(button, x, y)
Handles a mouse release event
return xPos, yPos
end
### Parameters
* `button` `number` The button that was released
* `x` `number` The x position of the release
* `y` `number` The y position of the release
--- Returns the relative position of the element or the given coordinates.
---@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
x, y = self.get("x"), self.get("y")
end
### Returns
* `boolean` `release` Whether the element was released on the element
local parentX, parentY = 1, 1
if self.parent then
parentX, parentY = self.parent:getRelativePosition()
end
## VisualElement:mouse_up(button, x, y)
Handles a mouse up event
local elementX = self.get("x")
local elementY = self.get("y")
### Parameters
* `button` `number` The button that was released
* `x` `number` The x position of the release
* `y` `number` The y position of the release
return x - (elementX - 1) - (parentX - 1),
y - (elementY - 1) - (parentY - 1)
end
### Returns
* `boolean` `release` Whether the element was released on the element
--- Sets the cursor position
--- @param x number The x position of the cursor
--- @param y number The y position of the cursor
--- @param blink boolean Whether the cursor should blink
function VisualElement:setCursor(x, y, blink)
if self.parent then
local absX, absY = self:getAbsolutePosition(x, y)
absX = max(self.get("x"), min(absX, self.get("width") + self.get("x") - 1))
return self.parent:setCursor(absX, absY, blink)
end
end
## VisualElement:multiBlit(x, y, width, height, text, fg, bg)
Draws a text character/fg/bg at the specified position with a certain size, used in the rendering system
--- Renders the element
--- @usage element:render()
function VisualElement:render()
if(not self.get("backgroundEnabled"))then
return
end
local width, height = self.get("width"), self.get("height")
self:multiBlit(1, 1, width, height, " ", tHex[self.get("foreground")], tHex[self.get("background")])
end
### Parameters
* `x` `number` The x position to draw
* `y` `number` The y position to draw
* `width` `number` The width of the element
* `height` `number` The height of the element
* `text` `string` The text char to draw
* `fg` `color` The foreground color
* `bg` `color` The background color
## VisualElement:render()
Renders the element
### Usage
```lua
element:render()
```
## VisualElement:setCursor(x, y, blink)
Sets the cursor position
### Parameters
* `x` `number` The x position of the cursor
* `y` `number` The y position of the cursor
* `blink` `boolean` Whether the cursor should blink
## VisualElement:textBg(x, y, text, bg)
Draws a text character with a background at the specified position, used in the rendering system
### Parameters
* `x` `number` The x position to draw
* `y` `number` The y position to draw
* `text` `string` The text char to draw
* `bg` `color` The background color
## VisualElement:textFg(x, y, text, fg)
Draws a text character at the specified position, used in the rendering system
### Parameters
* `x` `number` The x position to draw
* `y` `number` The y position to draw
* `text` `string` The text char to draw
* `fg` `color` The foreground color
return VisualElement