- Added a new system to dynamically require source from multiple locations (including web)

- Added the Collection Element and moved parts of the List logic to collection
- Added a State Management System
- Added a better system to change the position/size of elements
- Removed the state plugin
This commit is contained in:
Robert Jelic
2025-10-27 08:25:58 +01:00
parent 565209d63e
commit b96875a3e9
19 changed files with 1699 additions and 521 deletions

182
src/elements/Collection.lua Normal file
View File

@@ -0,0 +1,182 @@
local VisualElement = require("elements/VisualElement")
local CollectionEntry = require("libraries/collectionentry")
---@configDescription A collection of items
--- This is the Collection class. It provides a collection of items
---@class Collection : VisualElement
local Collection = setmetatable({}, VisualElement)
Collection.__index = Collection
Collection.defineProperty(Collection, "items", {default={}, type = "table"})
---@property selectable boolean true Whether items can be selected
Collection.defineProperty(Collection, "selectable", {default = true, type = "boolean"})
---@property multiSelection boolean false Whether multiple items can be selected at once
Collection.defineProperty(Collection, "multiSelection", {default = false, type = "boolean"})
---@property selectedBackground color blue Background color for selected items
Collection.defineProperty(Collection, "selectedBackground", {default = colors.blue, type = "color"})
---@property selectedForeground color white Text color for selected items
Collection.defineProperty(Collection, "selectedForeground", {default = colors.white, type = "color"})
---@event onSelect {index number, item table} Fired when an item is selected
--- Creates a new Collection instance
--- @shortDescription Creates a new Collection instance
--- @return Collection self The newly created Collection instance
--- @private
function Collection.new()
local self = setmetatable({}, Collection):__init()
self.class = Collection
return self
end
--- @shortDescription Initializes the Collection instance
--- @param props table The properties to initialize the element with
--- @param basalt table The basalt instance
--- @return Collection self The initialized instance
--- @protected
function Collection:init(props, basalt)
VisualElement.init(self, props, basalt)
self._entrySchema = {}
self.set("type", "Collection")
return self
end
--- Adds an item to the Collection
--- @shortDescription Adds an item to the Collection
--- @param text string|table The item to add (string or item table)
--- @return Collection self The Collection instance
--- @usage Collection:addItem("New Item")
--- @usage Collection:addItem({text="Item", callback=function() end})
function Collection:addItem(itemData)
if type(itemData) == "string" then
itemData = {text = itemData}
end
if itemData.selected == nil then
itemData.selected = false
end
local entry = CollectionEntry.new(self, itemData, self._entrySchema)
table.insert(self.get("items"), entry)
self:updateRender()
return entry
end
--- Removes an item from the Collection
--- @shortDescription Removes an item from the Collection
--- @param index number The index of the item to remove
--- @return Collection self The Collection instance
--- @usage Collection:removeItem(1)
function Collection:removeItem(index)
local items = self.get("items")
if type(index) == "number" then
table.remove(items, index)
else
for k,v in pairs(items)do
if v == index then
table.remove(items, k)
break
end
end
end
self:updateRender()
return self
end
--- Clears all items from the Collection
--- @shortDescription Clears all items from the Collection
--- @return Collection self The Collection instance
--- @usage Collection:clear()
function Collection:clear()
self.set("items", {})
self:updateRender()
return self
end
-- Gets the currently selected items
--- @shortDescription Gets the currently selected items
--- @return table selected Collection of selected items
--- @usage local selected = Collection:getSelectedItems()
function Collection:getSelectedItems()
local selected = {}
for i, item in ipairs(self.get("items")) do
if type(item) == "table" and item.selected then
local selectedItem = item
selectedItem.index = i
table.insert(selected, selectedItem)
end
end
return selected
end
--- Gets first selected item
--- @shortDescription Gets first selected item
--- @return table? selected The first item
function Collection:getSelectedItem()
local items = self.get("items")
for i, item in ipairs(items) do
if type(item) == "table" and item.selected then
return item
end
end
return nil
end
function Collection:selectItem(index)
local items = self.get("items")
if type(index) == "number" then
if items[index] and type(items[index]) == "table" then
items[index].selected = true
end
else
for k,v in pairs(items)do
if v == index then
if type(v) == "table" then
v.selected = true
end
break
end
end
end
self:updateRender()
return self
end
function Collection:unselectItem(index)
local items = self.get("items")
if type(index) == "number" then
if items[index] and type(items[index]) == "table" then
items[index].selected = false
end
else
for k,v in pairs(items)do
if v == index then
if type(items[k]) == "table" then
items[k].selected = false
end
break
end
end
end
self:updateRender()
return self
end
function Collection:clearItemSelection()
local items = self.get("items")
for i, item in ipairs(items) do
item.selected = false
end
return self
end
--- Registers a callback for the select event
--- @shortDescription Registers a callback for the select event
--- @param callback function The callback function to register
--- @return Collection self The Collection instance
--- @usage Collection:onSelect(function(index, item) print("Selected item:", index, item) end)
function Collection:onSelect(callback)
self:registerCallback("select", callback)
return self
end
return Collection