-- ------------------------------------------------------------------------------ -- -- TradeSkillMaster -- -- https://tradeskillmaster.com -- -- All Rights Reserved - Detailed license information included with addon. -- -- ------------------------------------------------------------------------------ -- --- SelectionScrollingTable UI Element Class. -- A selection scrolling table is a scrolling table which allows for selecting and deselecting individual rows. It is a -- subclass of the @{QueryScrollingTable} class. -- @classmod SelectionScrollingTable local _, TSM = ... local Table = TSM.Include("Util.Table") local TempTable = TSM.Include("Util.TempTable") local UIElements = TSM.Include("UI.UIElements") local SelectionScrollingTable = TSM.Include("LibTSMClass").DefineClass("SelectionScrollingTable", TSM.UI.QueryScrollingTable) UIElements.Register(SelectionScrollingTable) TSM.UI.SelectionScrollingTable = SelectionScrollingTable local private = { querySelectionScrollingTableLookup = {}, sortValuesTemp = {}, tempContextTable = {}, } local TEMP_CONTEXT_TABLE_DEFAULT = { colWidth = { selected = 16, }, colHidden = {}, } -- ============================================================================ -- Public Class Methods -- ============================================================================ function SelectionScrollingTable.__init(self) self.__super:__init() self._selectedData = {} self._selectionEnabledFunc = nil self._rightClickToggle = true end function SelectionScrollingTable.Acquire(self) self.__super:Acquire() -- temporarily set a context table so we can create the table columns (should be overridden later) wipe(private.tempContextTable) self.__super:SetContextTable(private.tempContextTable, TEMP_CONTEXT_TABLE_DEFAULT) self:GetScrollingTableInfo() :NewColumn("selected", true) :SetTitleIcon("iconPack.14x14/Checkmark/Default") :SetWidth(14) :SetIconSize(12) :SetFont("ITEM_BODY3") :SetJustifyH("CENTER") :SetIconInfo(nil, private.GetSelectedIcon) :DisableHiding() :Commit() :Commit() end function SelectionScrollingTable.Release(self) private.querySelectionScrollingTableLookup[self._query] = nil wipe(self._selectedData) self._selectionEnabledFunc = nil self.__super:Release() end --- Sets the @{DatabaseQuery} source for this table. -- This query is used to populate the entries in the selection scrolling table. -- @tparam SelectionScrollingTable self The selection scrolling table object -- @tparam DatabaseQuery query The query object -- @tparam[opt=false] bool redraw Whether or not to redraw the selection scrolling table -- @treturn SelectionScrollingTable The selection scrolling table object function SelectionScrollingTable.SetQuery(self, query, redraw) if self._query then private.querySelectionScrollingTableLookup[self._query] = nil end private.querySelectionScrollingTableLookup[query] = self self.__super:SetQuery(query, redraw) return self end --- Selects all items. -- @tparam SelectionScrollingTable self The selection scrolling table object function SelectionScrollingTable.SelectAll(self) for _, uuid in ipairs(self._data) do self._selectedData[uuid] = true end self:_UpdateData() self:Draw() if self._onSelectionChangedHandler then self._onSelectionChangedHandler(self) end end --- Clear the selection. -- @tparam SelectionScrollingTable self The selection scrolling table object function SelectionScrollingTable.ClearSelection(self) wipe(self._selectedData) self:_UpdateData() self:Draw() if self._onSelectionChangedHandler then self._onSelectionChangedHandler(self) end end --- Sets a selection enabled function. -- @tparam SelectionScrollingTable self The selection scrolling table object -- @tparam function func A funciton which gets called with data to determine if it's selectable or not -- @treturn SelectionScrollingTable The selection scrolling table object function SelectionScrollingTable.SetIsSelectionEnabledFunc(self, func) self._selectionEnabledFunc = func return self end --- Toggles the selection of a record. -- @tparam SelectionScrollingTable self The selection scrolling table object -- @tparam ?table data The record to toggle the selection of -- @treturn SelectionScrollingTable The selection scrolling table object function SelectionScrollingTable.SetSelection(self, data) if data and self._selectionValidator and not self:_selectionValidator(self._query:GetResultRowByUUID(data)) then assert(not self._selectedData[data]) return self end self._selectedData[data] = not self._selectedData[data] or nil for _, row in ipairs(self._rows) do if row:GetData() == data then self:_SetRowData(row, data) break end end if self._sortCol == "selected" then self:_UpdateData() self:Draw() end if self._onSelectionChangedHandler then self._onSelectionChangedHandler(self) end return self end --- Gets whether or not all of the items are currently selected. -- @tparam SelectionScrollingTable self The selection scrolling table object -- @treturn boolean Whether or not all of the selection is selected function SelectionScrollingTable.IsAllSelected(self) for _, uuid in ipairs(self._data) do if not self._selectedData[uuid] then return false end end return true end --- Gets whether or not the selection is currently cleared. -- @tparam SelectionScrollingTable self The selection scrolling table object -- @treturn boolean Whether or not the selection is cleared function SelectionScrollingTable.IsSelectionCleared(self) return not next(self._selectedData) end --- Gets the current selection table. -- @tparam SelectionScrollingTable self The selection scrolling table object -- @treturn table A table where the key is the data and the value is whether or not it's selected (only selected entries -- are in the table) function SelectionScrollingTable.SelectionIterator(self) return private.SelectionIteratorHelper, self end --- Sets the context table. -- This table can be used to preserve the table configuration across lifecycles of the scrolling table and even WoW -- sessions if it's within the settings DB. -- @tparam SelectionScrollingTable self The selection scrolling table object -- @tparam table tbl The context table -- @tparam table defaultTbl The default table (required fields: `colWidth`) -- @treturn SelectionScrollingTable The selection scrolling table object function SelectionScrollingTable.SetContextTable(self, tbl, defaultTbl) assert(defaultTbl.colWidth.selected) self.__super:SetContextTable(tbl, defaultTbl) return self end -- ============================================================================ -- Private Class Methods -- ============================================================================ function SelectionScrollingTable._IsSelected(self, data) return self._selectedData[data] == 1 end function SelectionScrollingTable._UpdateData(self) self.__super:_UpdateData() -- clear any old selection context local hasData = TempTable.Acquire() for _, data in ipairs(self._data) do hasData[data] = true end for data in pairs(self._selectedData) do if not hasData[data] then self._selectedData[data] = nil end end TempTable.Release(hasData) if self._sortCol == "selected" then local selectedValue = self._sortAscending and -1 or 1 for _, uuid in ipairs(self._data) do private.sortValuesTemp[uuid] = self._selectedData[uuid] and selectedValue or 0 end Table.SortWithValueLookup(self._data, private.sortValuesTemp) wipe(private.sortValuesTemp) end end function SelectionScrollingTable._ToggleSort(self, id) if id ~= "selected" then return self.__super:_ToggleSort(id) end if id == self._sortCol then self._sortAscending = not self._sortAscending else self._sortCol = id self._sortAscending = true end self:_UpdateData() self:Draw() end -- ============================================================================ -- Private Helper Functions -- ============================================================================ function private.SelectionIteratorHelper(self, uuid) uuid = next(self._selectedData, uuid) if not uuid then return end return uuid, self._query:GetResultRowByUUID(uuid) end function private.GetSelectedIcon(row) local self = private.querySelectionScrollingTableLookup[row:GetQuery()] return self._selectedData[row:GetUUID()] and "iconPack.14x14/Checkmark/Default" or 0 end