Files
Basalt2/src/elements/Collection.lua
Robert Jelic 41bd5bdf04 - Added DropDown Scrollbar
- Added List Scrollbar
- Added Statemanagementsystem for XML
2025-10-29 09:10:23 +01:00

241 lines
7.5 KiB
Lua

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
self:updateRender()
return self
end
--- Gets the index of the first selected item
--- @shortDescription Gets the index of the first selected item
--- @return number? index The index of the first selected item, or nil if none selected
--- @usage local index = Collection:getSelectedIndex()
function Collection:getSelectedIndex()
local items = self.get("items")
for i, item in ipairs(items) do
if type(item) == "table" and item.selected then
return i
end
end
return nil
end
--- Selects the next item in the collection
--- @shortDescription Selects the next item
--- @return Collection self The Collection instance
function Collection:selectNext()
local items = self.get("items")
local currentIndex = self:getSelectedIndex()
if not currentIndex then
if #items > 0 then
self:selectItem(1)
end
elseif currentIndex < #items then
if not self.get("multiSelection") then
self:clearItemSelection()
end
self:selectItem(currentIndex + 1)
end
self:updateRender()
return self
end
--- Selects the previous item in the collection
--- @shortDescription Selects the previous item
--- @return Collection self The Collection instance
function Collection:selectPrevious()
local items = self.get("items")
local currentIndex = self:getSelectedIndex()
if not currentIndex then
if #items > 0 then
self:selectItem(#items)
end
elseif currentIndex > 1 then
if not self.get("multiSelection") then
self:clearItemSelection()
end
self:selectItem(currentIndex - 1)
end
self:updateRender()
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