|
|
|
|
local _, S = ...
|
|
|
|
|
local pairs, ipairs, string, type, time = pairs, ipairs, string, type, time
|
|
|
|
|
|
|
|
|
|
S.API = LibStub:NewLibrary("Sorted.", 1)
|
|
|
|
|
|
|
|
|
|
S.API.Color = S.Color
|
|
|
|
|
S.API.IsPlayingCharacterSelected = S.IsPlayingCharacterSelected
|
|
|
|
|
S.API.PrintTable = S.Utils.PrintTable
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- Utilities
|
|
|
|
|
S.API.GetValueIcon = S.Utils.GetValueIcon
|
|
|
|
|
S.API.FormatValueStringNoIcon = S.Utils.FormatValueStringNoIcon
|
|
|
|
|
S.API.GetValueColor = S.Utils.GetValueColor
|
|
|
|
|
|
|
|
|
|
-- Updates the data of all items and all their displayed info
|
|
|
|
|
function S.API.TriggerFullUpdate()
|
|
|
|
|
S.Data.UpdateBagContents()
|
|
|
|
|
end
|
|
|
|
|
-- Updates the data and display of one column
|
|
|
|
|
function S.API.UpdateColumn(columnKey)
|
|
|
|
|
for _, itemList in pairs(S.itemLists) do
|
|
|
|
|
for _, entryButton in pairs(itemList.entryButtons) do
|
|
|
|
|
if entryButton.data.bag then
|
|
|
|
|
-- Update data in the saved variable Sorted_Data and in the entryButton
|
|
|
|
|
itemList.columns[columnKey].preSortingFunc(S.Data.GetItem(entryButton.data.bag, entryButton.data.slot))
|
|
|
|
|
itemList.columns[columnKey].preSortingFunc(entryButton.data)
|
|
|
|
|
itemList.columns[columnKey].UpdateElement(entryButton.columnElements[columnKey], entryButton.data)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function S.API.DefaultItemSort(itemData1, itemData2)
|
|
|
|
|
if itemData1.quality == itemData2.quality then
|
|
|
|
|
if itemData1.effectiveILvl == itemData2.effectiveILvl then
|
|
|
|
|
if itemData1.name == itemData2.name then
|
|
|
|
|
if itemData1.combinedCount == itemData2.combinedCount then
|
|
|
|
|
return itemData1.bag * 36 + itemData1.slot > itemData2.bag * 36 + itemData2.slot
|
|
|
|
|
end
|
|
|
|
|
return itemData1.combinedCount > itemData2.combinedCount
|
|
|
|
|
end
|
|
|
|
|
return itemData1.name < itemData2.name
|
|
|
|
|
end
|
|
|
|
|
return itemData1.effectiveILvl > itemData2.effectiveILvl
|
|
|
|
|
end
|
|
|
|
|
return itemData1.quality > itemData2.quality
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Sorts itemData1 and itemData2 by the supplied values, value1 and value2. Resorts to DefaultItemSort if identical.
|
|
|
|
|
function S.API.Sort(inverse, value1, value2, itemData1, itemData2)
|
|
|
|
|
return S.Sort.ByValue(inverse, value1, value2, itemData1, itemData2, S.API.DefaultItemSort)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--[[
|
|
|
|
|
Adds a new column, attaching a new element to every row in the table.
|
|
|
|
|
Provide methods for creating these elements, and updating them when the item changes.
|
|
|
|
|
|
|
|
|
|
Parameters:
|
|
|
|
|
key - STRING - Unique identifier of the column.
|
|
|
|
|
name - STRING - Name of the column displayed in the right-click dropdown menu.
|
|
|
|
|
width - NUMBER - Default width, can be resized by user.
|
|
|
|
|
|
|
|
|
|
CreateElement(frame) - FUNCTION
|
|
|
|
|
Creates the displayed fontstring, or texture, or button, etc. for a single item.
|
|
|
|
|
Parameters:
|
|
|
|
|
frame - FRAME - The region of the intersection between column and row, in which to place widgets.
|
|
|
|
|
|
|
|
|
|
UpdateElement(self, itemData) - FUNCTION
|
|
|
|
|
Updates the element of a single item.
|
|
|
|
|
Parameters:
|
|
|
|
|
self - FRAME - The frame created by CreateElement.
|
|
|
|
|
itemData - TABLE - Contains the following data about the item, plus anything added by S.API.AddDataToItem():
|
|
|
|
|
{
|
|
|
|
|
["filtered"] = Whether the item should be greyed out (because it doesn't fit the selected category, or doesn't match the search)
|
|
|
|
|
["bag"] = Container ID of the containing bag
|
|
|
|
|
["slot"] = Slot ID of the item in the bag
|
|
|
|
|
["name"] = Item's name
|
|
|
|
|
["link"] = Item link
|
|
|
|
|
["texture"] = Numberic ID of the item's icon
|
|
|
|
|
["itemID"] = Item ID
|
|
|
|
|
["classID"] = ID of the item's type
|
|
|
|
|
["subClassID"] = ID of the item's subtype
|
|
|
|
|
["expacID"] = Expansion number
|
|
|
|
|
["hasNoValue"] = Whether the item can't be sold
|
|
|
|
|
["count"] = SHOULDN'T BE USED. Quantity items in this stack.
|
|
|
|
|
["combinedCount"] = Quantity, including any combined stacks.
|
|
|
|
|
["equipLoc"] = ItemEquipLoc, e.g. "INVTYPE_TABARD"
|
|
|
|
|
["effectiveILvl"] = Item level, corrected for any scaling
|
|
|
|
|
["bindType"] = 0: No binding, 1: BoP, 2: BoE, 3: BoU
|
|
|
|
|
["bound"] = Whether the item is soulbound
|
|
|
|
|
["key"] = The item link with some unnecessary portions removed. Used to identify if two items are equivalent
|
|
|
|
|
["value"] = The value, in copper, of ONE item sold to a vendor. Multiply by combinedCount for the total value.
|
|
|
|
|
["minLevel"] = Character level required to use the item
|
|
|
|
|
["quality"] = Enum.ItemQuality, e.g. 0 for Poor, 1 for Common, etc. Sorted uses 8 for WoWTokens and Mythic Keystones
|
|
|
|
|
["color1"] = ColorMixin. Color of the item's quality.
|
|
|
|
|
["color2"] = ColorMixin. Brightened color1 for highlighting.
|
|
|
|
|
["tinted"] = ColorMixin. Grayed out color1 for filtering.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UpdateIcon(self, iconSize, borderThickness, iconShape) - Optional
|
|
|
|
|
If the element is an icon, consider using this to apply skinning settings
|
|
|
|
|
Parameters:
|
|
|
|
|
self - FRAME - The frame created by CreateElement.
|
|
|
|
|
iconSize - NUMBER - Value of the Icon Size setting.
|
|
|
|
|
borderThickness - NUMBER - Value of the Border Thickness setting.
|
|
|
|
|
iconShape - NUMBER - 0: Square, 1: Round
|
|
|
|
|
]]
|
|
|
|
|
function S.API:AddItemColumn(key, name, width, CreateElement, UpdateElement, UpdateIcon)
|
|
|
|
|
S.ItemColumns[key] = {
|
|
|
|
|
["name"] = name,
|
|
|
|
|
["width"] = width,
|
|
|
|
|
["CreateElement"] = CreateElement,
|
|
|
|
|
["UpdateElement"] = UpdateElement,
|
|
|
|
|
["UpdateIcon"] = UpdateIcon,
|
|
|
|
|
["sortMethods"] = {}
|
|
|
|
|
}
|
|
|
|
|
for _, itemList in pairs(S.itemLists) do
|
|
|
|
|
itemList:AddColumn(key)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--[[
|
|
|
|
|
Adds a sort method to a column.
|
|
|
|
|
If more than one is added, then repeatedly clicking the column heading cycles through the sort methods.
|
|
|
|
|
|
|
|
|
|
Parameters:
|
|
|
|
|
columnKey - STRING - Key of the column to add the sort method to.
|
|
|
|
|
title - STRING - Text to display on the column heading.
|
|
|
|
|
|
|
|
|
|
Sort(asc, itemData1, itemData2) - FUNCTION
|
|
|
|
|
Returns true if itemData1 comes before itemData2.
|
|
|
|
|
Should use the API's DefaultItemSort(itemData1, itemData2) if they are identical.
|
|
|
|
|
|
|
|
|
|
Parameters:
|
|
|
|
|
asc - BOOLEAN - Whether the user has sorted by ascending
|
|
|
|
|
itemData1 - TABLE - Data table of the first item
|
|
|
|
|
itemData2 - TABLE - Data table of the second item
|
|
|
|
|
|
|
|
|
|
inverse - BOOLEAN - Optional - Set to true if sorting should start ascending instead of descending
|
|
|
|
|
]]
|
|
|
|
|
function S.API:AddSortMethod(columnKey, title, Sort, inverse)
|
|
|
|
|
table.insert(S.ItemColumns[columnKey].sortMethods, {
|
|
|
|
|
["title"] = title,
|
|
|
|
|
["func"] = Sort,
|
|
|
|
|
["inverse"] = inverse
|
|
|
|
|
})
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--[[
|
|
|
|
|
For performance, loads an item's table with any extra data needed for sorting, or for UpdateElement(self, ITEMDATA).
|
|
|
|
|
Be careful not to add too much, since this table is saved between sessions.
|
|
|
|
|
This also allows the data to be accessed on other characters.
|
|
|
|
|
|
|
|
|
|
Parameters:
|
|
|
|
|
columnKey - STRING - Key of the column to add the method to. (UNUSED)
|
|
|
|
|
func(itemData) - FUNCTION
|
|
|
|
|
Using the data in itemData, add any extra values necessary for sorting to the table.
|
|
|
|
|
Parameters:
|
|
|
|
|
itemData - TABLE
|
|
|
|
|
]]
|
|
|
|
|
function S.API:AddDataToItem(columnKey, func)
|
|
|
|
|
S.Data.AddDataToItem(func)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
--[[
|
|
|
|
|
|
|
|
|
|
-- EXAMPLE
|
|
|
|
|
-- Remove the double square brackets, before and after, to test.
|
|
|
|
|
|
|
|
|
|
local Sorted = LibStub("Sorted.")
|
|
|
|
|
|
|
|
|
|
-- Adds a new column that displays the bag and slot ID
|
|
|
|
|
local CreateElement = function(f)
|
|
|
|
|
f.text = f:CreateFontString(nil, "OVERLAY", "SortedFont")
|
|
|
|
|
f.text:SetAllPoints()
|
|
|
|
|
f.text:SetJustifyH("CENTER")
|
|
|
|
|
f.text:SetTextColor(Sorted.Color.YELLOWISH_TEXT:GetRGB())
|
|
|
|
|
end
|
|
|
|
|
local UpdateElement = function(f, data)
|
|
|
|
|
f.text:SetText(data.bag..", "..data.slot)
|
|
|
|
|
end
|
|
|
|
|
Sorted:AddItemColumn("BAGSLOT", "Bag and Slot", 48, CreateElement, UpdateElement)
|
|
|
|
|
|
|
|
|
|
-- Add a sort method that sorts first by bag, then by slot
|
|
|
|
|
local Sort = function(asc, data1, data2)
|
|
|
|
|
if data1.bag == data2.bag then
|
|
|
|
|
if data1.slot == data2.slot then
|
|
|
|
|
return Sorted.DefaultItemSort(data1, data2)
|
|
|
|
|
end
|
|
|
|
|
if asc then
|
|
|
|
|
return data1.slot < data2.slot
|
|
|
|
|
else
|
|
|
|
|
return data1.slot > data2.slot
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
if asc then
|
|
|
|
|
return data1.bag < data2.bag
|
|
|
|
|
else
|
|
|
|
|
return data1.bag > data2.bag
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
Sorted:AddSortMethod("BAGSLOT", "Bag", Sort, false)
|
|
|
|
|
|
|
|
|
|
-- Add a secondary sort method that ignores the bag and only sorts by slot
|
|
|
|
|
Sort = function(asc, data1, data2)
|
|
|
|
|
if data1.slot == data2.slot then
|
|
|
|
|
return Sorted.DefaultItemSort(data1, data2)
|
|
|
|
|
end
|
|
|
|
|
if asc then
|
|
|
|
|
return data1.slot < data2.slot
|
|
|
|
|
else
|
|
|
|
|
return data1.slot > data2.slot
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
Sorted:AddSortMethod("BAGSLOT", "Slot", Sort, false)
|
|
|
|
|
|
|
|
|
|
]]
|