TradeSkillMaster/Core/Service/Tooltip/Core.lua

276 lines
8.8 KiB
Lua
Raw Permalink Normal View History

2020-11-13 14:13:12 -05:00
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local _, TSM = ...
local Tooltip = TSM:NewPackage("Tooltip")
local ItemString = TSM.Include("Util.ItemString")
local ObjectPool = TSM.Include("Util.ObjectPool")
local ItemTooltip = TSM.Include("Service.ItemTooltip")
local Settings = TSM.Include("Service.Settings")
local LibTSMClass = TSM.Include("LibTSMClass")
local TooltipInfo = LibTSMClass.DefineClass("TooltipInfo")
local TooltipEntry = LibTSMClass.DefineClass("TooltipEntry")
local private = {
entryObjPool = ObjectPool.New("TOOLTIP_ENTRY", TooltipEntry),
settings = nil,
registeredInfo = {},
settingsBuilder = nil,
}
local ITER_INDEX_PART_MULTIPLE = 1000
-- ============================================================================
-- Module Functions
-- ============================================================================
function Tooltip.OnInitialize()
private.settings = Settings.NewView()
:AddKey("global", "tooltipOptions", "moduleTooltips")
:AddKey("global", "tooltipOptions", "customPriceTooltips")
:AddKey("global", "tooltipOptions", "vendorBuyTooltip")
:AddKey("global", "tooltipOptions", "vendorSellTooltip")
:AddKey("global", "tooltipOptions", "groupNameTooltip")
:AddKey("global", "tooltipOptions", "detailedDestroyTooltip")
:AddKey("global", "tooltipOptions", "millTooltip")
:AddKey("global", "tooltipOptions", "prospectTooltip")
:AddKey("global", "tooltipOptions", "deTooltip")
:AddKey("global", "tooltipOptions", "transformTooltip")
:AddKey("global", "tooltipOptions", "operationTooltips")
:AddKey("global", "tooltipOptions", "inventoryTooltipFormat")
ItemTooltip.SetWrapperPopulateFunction(private.PopulateTooltip)
private.settingsBuilder = ItemTooltip.CreateBuilder()
end
function Tooltip.CreateInfo()
return TooltipInfo()
end
function Tooltip.Register(info)
info:_CheckDefaults()
tinsert(private.registeredInfo, info)
end
function Tooltip.SettingsLineIterator()
assert(not private.settingsBuilder:_Prepare(ItemString.GetPlaceholder(), 1))
return private.SettingsLineIteratorHelper, nil, 0
end
-- ============================================================================
-- TooltipInfo Class
-- ============================================================================
function TooltipInfo.__init(self)
self._headingLeft = nil
self._headingRight = nil
self._settingsModule = nil
self._entries = {}
end
function TooltipInfo.SetHeadings(self, left, right)
self._headingLeft = left
self._headingRight = right
return self
end
function TooltipInfo.SetSettingsModule(self, settingsModule)
self._settingsModule = settingsModule
return self
end
function TooltipInfo.AddSettingEntry(self, key, defaultValue, populateFunc, populateArg)
if defaultValue == nil then
defaultValue = private.settings:GetDefaultReadOnly(key)
end
assert(type(defaultValue) == "boolean")
local entry = private.entryObjPool:Get()
entry:_Acquire(self, key, true, false, defaultValue, populateFunc, populateArg)
tinsert(self._entries, entry)
return self
end
function TooltipInfo.AddSettingValueEntry(self, key, setValue, clearValue, populateFunc, populateArg)
local entry = private.entryObjPool:Get()
entry:_Acquire(self, key, setValue, clearValue, nil, populateFunc, populateArg)
tinsert(self._entries, entry)
return self
end
function TooltipInfo.DeleteSettingsByKeyMatch(self, matchStr)
for i = #self._entries, 1, -1 do
local entry = self._entries[i]
if entry:KeyMatches(matchStr) then
tremove(self._entries, i)
entry:_Release()
private.entryObjPool:Recycle(entry)
end
end
end
function TooltipInfo._CheckDefaults(self)
if self._settingsModule and not private.settings.moduleTooltips[self._settingsModule] then
-- populate all the default values
private.settings.moduleTooltips[self._settingsModule] = {}
for _, entry in ipairs(self._entries) do
entry:_ResetSetting()
end
end
end
function TooltipInfo._GetSettingsTable(self)
if self._settingsModule then
return private.settings.moduleTooltips[self._settingsModule]
else
return private.settings
end
end
function TooltipInfo._Populate(self, tooltip, itemString)
local headingRightText = self._headingRight and self._headingRight(tooltip, itemString) or nil
tooltip:StartSection(self._headingLeft, headingRightText)
for _, entry in ipairs(self._entries) do
if entry:IsEnabled() then
entry:_Populate(tooltip, itemString)
end
end
tooltip:EndSection()
end
function TooltipInfo._GetEntry(self, index)
return self._entries[index]
end
-- ============================================================================
-- TooltipEntry Class
-- ============================================================================
function TooltipEntry.__init(self)
self._info = nil
self._settingKey = nil
self._settingSetValue = nil
self._settingClearValue = nil
self._settingDefaultValue = nil
self._populateFunc = nil
self._populateArg = nil
end
function TooltipEntry._Acquire(self, info, key, setValue, clearValue, defaultValue, populateFunc, populateArg)
assert(setValue == nil or setValue, "'setValue' must be truthy")
assert(info and key and populateFunc)
assert(clearValue ~= nil or defaultValue ~= nil)
self._info = info
self._settingKey = key
self._settingSetValue = setValue or true
self._settingClearValue = clearValue or false
self._settingDefaultValue = defaultValue
self._populateFunc = populateFunc
self._populateArg = populateArg
end
function TooltipEntry._Release(self)
self._info = nil
self._settingKey = nil
self._settingSetValue = nil
self._settingClearValue = nil
self._settingDefaultValue = nil
self._populateFunc = nil
self._populateArg = nil
end
function TooltipEntry.GetSettingInfo(self)
local tbl = self._info:_GetSettingsTable()
local key, key2, extra = strsplit(".", self._settingKey)
assert(key and not extra)
if key2 then
tbl = tbl[key]
key = key2
end
assert(type(tbl) == "table")
return tbl, key
end
function TooltipEntry.IsEnabled(self)
local settingTbl, settingKey = self:GetSettingInfo()
local settingValue = settingTbl[settingKey]
if settingValue == nil then
assert(self._settingDefaultValue ~= nil)
settingTbl[settingKey] = self._settingDefaultValue
settingValue = settingTbl[settingKey]
end
return settingValue == self._settingSetValue
end
function TooltipEntry.KeyMatches(self, matchStr)
return strmatch(self._settingKey, matchStr) and true or false
end
function TooltipEntry._ResetSetting(self, value)
local tbl = self._info:_GetSettingsTable()
if self._settingDefaultValue ~= nil then
tbl[self._settingKey] = self._settingDefaultValue
elseif self._settingClearValue ~= nil then
tbl[self._settingKey] = self._settingClearValue
else
error("Invalid setting info")
end
end
function TooltipEntry._Populate(self, tooltip, itemString)
self._populateFunc(tooltip, itemString, self._populateArg)
end
-- ============================================================================
-- Private Helper Functions
-- ============================================================================
function private.PopulateTooltip(tooltip, itemString)
for _, info in ipairs(private.registeredInfo) do
info:_Populate(tooltip, itemString)
end
end
function private.SettingsLineIteratorHelper(_, index)
local infoIndex = floor(index / (ITER_INDEX_PART_MULTIPLE ^ 2))
local entryIndex = floor(index / ITER_INDEX_PART_MULTIPLE) % ITER_INDEX_PART_MULTIPLE
local lineIndex = index % ITER_INDEX_PART_MULTIPLE
local info, entry = nil, nil
while lineIndex >= private.settingsBuilder:GetNumLines() do
-- move to the next entry
info = private.registeredInfo[infoIndex]
entryIndex = entryIndex + 1
entry = info and info:_GetEntry(entryIndex)
if entry then
private.settingsBuilder:SetDisabled(not entry:IsEnabled())
entry:_Populate(private.settingsBuilder, ItemString.GetPlaceholder())
private.settingsBuilder:SetDisabled(false)
else
-- move to the next info
if infoIndex > 0 then
private.settingsBuilder:EndSection()
end
infoIndex = infoIndex + 1
info = private.registeredInfo[infoIndex]
if info then
private.settingsBuilder:StartSection(info._headingLeft)
entryIndex = 0
else
return
end
end
end
lineIndex = lineIndex + 1
index = infoIndex * ITER_INDEX_PART_MULTIPLE ^ 2 + entryIndex * ITER_INDEX_PART_MULTIPLE + lineIndex
local leftText, rightText, lineColor = private.settingsBuilder:GetLine(lineIndex)
assert(infoIndex < ITER_INDEX_PART_MULTIPLE and entryIndex < ITER_INDEX_PART_MULTIPLE and lineIndex < ITER_INDEX_PART_MULTIPLE)
return index, leftText, rightText, lineColor
end