241 lines
7.5 KiB
Lua
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 |