You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

219 lines
8.8 KiB

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)
]]