190 lines
7.1 KiB
Lua
190 lines
7.1 KiB
Lua
-- ------------------------------------------------------------------------------ --
|
|
-- TradeSkillMaster --
|
|
-- https://tradeskillmaster.com --
|
|
-- All Rights Reserved - Detailed license information included with addon. --
|
|
-- ------------------------------------------------------------------------------ --
|
|
|
|
--- ApplicationGroupTree UI Element Class.
|
|
-- An application group tree displays the group tree in a way which allows the user to select any number of them. This
|
|
-- element is used wherever the user needs to select groups to perform some action on. It is a subclass of the
|
|
-- @{GroupTree} class.
|
|
-- @classmod ApplicationGroupTree
|
|
|
|
local _, TSM = ...
|
|
local TempTable = TSM.Include("Util.TempTable")
|
|
local UIElements = TSM.Include("UI.UIElements")
|
|
local ApplicationGroupTree = TSM.Include("LibTSMClass").DefineClass("ApplicationGroupTree", TSM.UI.GroupTree)
|
|
UIElements.Register(ApplicationGroupTree)
|
|
TSM.UI.ApplicationGroupTree = ApplicationGroupTree
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
-- Public Class Methods
|
|
-- ============================================================================
|
|
|
|
function ApplicationGroupTree.__init(self)
|
|
self.__super:__init()
|
|
self._selectedGroupsChangedHandler = nil
|
|
end
|
|
|
|
function ApplicationGroupTree.Release(self)
|
|
self._selectedGroupsChangedHandler = nil
|
|
self.__super:Release()
|
|
end
|
|
|
|
--- Registers a script handler.
|
|
-- @tparam ApplicationGroupTree self The application group tree object
|
|
-- @tparam string script The script to register for (supported scripts: `OnGroupSelectionChanged`)
|
|
-- @tparam function handler The script handler which will be called with the application group tree object followed by
|
|
-- any arguments to the script
|
|
-- @treturn ApplicationGroupTree The application group tree object
|
|
function ApplicationGroupTree.SetScript(self, script, handler)
|
|
if script == "OnGroupSelectionChanged" then
|
|
self._selectedGroupsChangedHandler = handler
|
|
else
|
|
error("Unknown ApplicationGroupTree script: "..tostring(script))
|
|
end
|
|
return self
|
|
end
|
|
|
|
--- Iterates through the selected groups.
|
|
-- @tparam ApplicationGroupTree self The application group tree object
|
|
-- @return Iterator with the following fields: `index, groupPath`
|
|
function ApplicationGroupTree.SelectedGroupsIterator(self)
|
|
local groups = TempTable.Acquire()
|
|
for _, groupPath in ipairs(self._allData) do
|
|
if self:_IsSelected(groupPath) then
|
|
tinsert(groups, groupPath)
|
|
end
|
|
end
|
|
return TempTable.Iterator(groups)
|
|
end
|
|
|
|
--- Sets the context table.
|
|
-- This table can be used to preserve selection state across lifecycles of the application group tree and even WoW
|
|
-- sessions if it's within the settings DB.
|
|
-- @see GroupTree.SetContextTable
|
|
-- @tparam ApplicationGroupTree self The application group tree object
|
|
-- @tparam table tbl The context table
|
|
-- @tparam table defaultTbl The default table (required fields: `unselected` OR `selected`, `collapsed`)
|
|
-- @treturn ApplicationGroupTree The application group tree object
|
|
function ApplicationGroupTree.SetContextTable(self, tbl, defaultTbl)
|
|
if defaultTbl.unselected then
|
|
assert(type(defaultTbl.unselected) == "table" and not defaultTbl.selected)
|
|
tbl.unselected = tbl.unselected or CopyTable(defaultTbl.unselected)
|
|
tbl.selected = nil
|
|
else
|
|
assert(type(defaultTbl.selected) == "table" and not defaultTbl.unselected)
|
|
tbl.selected = tbl.selected or CopyTable(defaultTbl.selected)
|
|
tbl.unselected = nil
|
|
end
|
|
self.__super:SetContextTable(tbl, defaultTbl)
|
|
return self
|
|
end
|
|
|
|
--- Gets whether or not a group is currently selected.
|
|
-- @tparam ApplicationGroupTree self The application group tree object
|
|
-- @tparam string groupPath The group to check
|
|
-- @treturn boolean Whether or not the group is selected
|
|
function ApplicationGroupTree.IsGroupSelected(self, groupPath)
|
|
return self:_IsSelected(groupPath)
|
|
end
|
|
|
|
--- Gets whether or not a group is currently selected.
|
|
-- @tparam ApplicationGroupTree self The application group tree object
|
|
-- @tparam string groupPath The group to set the selected state of
|
|
-- @tparam boolean selected Whether or not the group should be selected
|
|
-- @treturn ApplicationGroupTree The application group tree object
|
|
function ApplicationGroupTree.SetGroupSelected(self, groupPath, selected)
|
|
self:_SetSelected(groupPath, selected)
|
|
return self
|
|
end
|
|
|
|
--- Gets whether or not the selection is cleared.
|
|
-- @tparam ApplicationGroupTree self The application group tree object
|
|
-- @tparam[opt=false] boolean updateData Whether or not to update the data first
|
|
-- @treturn boolean Whether or not the selection is cleared
|
|
function ApplicationGroupTree.IsSelectionCleared(self, updateData)
|
|
if updateData then
|
|
self:_UpdateData()
|
|
end
|
|
for _, groupPath in ipairs(self._searchStr == "" and self._allData or self._data) do
|
|
if self:_IsSelected(groupPath) then
|
|
return false
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
--- Toggle the selection state of the application group tree.
|
|
-- @tparam ApplicationGroupTree self The application group tree object
|
|
-- @treturn ApplicationGroupTree The application group tree object
|
|
function ApplicationGroupTree.ToggleSelectAll(self)
|
|
local isCleared = self:IsSelectionCleared()
|
|
for _, groupPath in ipairs(self._searchStr == "" and self._allData or self._data) do
|
|
self:_SetSelected(groupPath, isCleared)
|
|
end
|
|
self:Draw()
|
|
if self._selectedGroupsChangedHandler then
|
|
self:_selectedGroupsChangedHandler()
|
|
end
|
|
return self
|
|
end
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
-- Private Class Methods
|
|
-- ============================================================================
|
|
|
|
function ApplicationGroupTree._UpdateData(self)
|
|
self.__super:_UpdateData()
|
|
-- remove data which is no longer present from _contextTable
|
|
local selectedGroups = TempTable.Acquire()
|
|
for _, groupPath in ipairs(self._allData) do
|
|
if self:_IsSelected(groupPath) then
|
|
selectedGroups[groupPath] = true
|
|
end
|
|
end
|
|
wipe(self._contextTable.selected or self._contextTable.unselected)
|
|
for _, groupPath in ipairs(self._allData) do
|
|
self:_SetSelected(groupPath, selectedGroups[groupPath])
|
|
end
|
|
TempTable.Release(selectedGroups)
|
|
end
|
|
|
|
function ApplicationGroupTree._IsSelected(self, data)
|
|
if self._contextTable.unselected then
|
|
return not self._contextTable.unselected[data]
|
|
else
|
|
return self._contextTable.selected[data]
|
|
end
|
|
end
|
|
|
|
function ApplicationGroupTree._SetSelected(self, data, selected)
|
|
if self._contextTable.unselected then
|
|
self._contextTable.unselected[data] = not selected or nil
|
|
else
|
|
self._contextTable.selected[data] = selected or nil
|
|
end
|
|
end
|
|
|
|
function ApplicationGroupTree._HandleRowClick(self, data, mouseButton)
|
|
if mouseButton == "RightButton" then
|
|
self.__super:_HandleRowClick(data, mouseButton)
|
|
return
|
|
end
|
|
self:_SetSelected(data, not self:_IsSelected(data))
|
|
-- also set the selection for all child groups to the same as this group
|
|
for _, groupPath in ipairs(self._allData) do
|
|
if TSM.Groups.Path.IsChild(groupPath, data) and data ~= TSM.CONST.ROOT_GROUP_PATH then
|
|
self:_SetSelected(groupPath, self:_IsSelected(data))
|
|
end
|
|
end
|
|
self:Draw()
|
|
if self._selectedGroupsChangedHandler then
|
|
self:_selectedGroupsChangedHandler()
|
|
end
|
|
end
|