Compare with Previous | Blame | View Log
--[[ Name: LibGratuity-3.0 Revision: $Rev: 42 $ Author: Tekkub Stoutwrithe (tekkub@gmail.com) SVN: svn://svn.wowace.com/root/trunk/LibGratuity-3.0 Description: Tooltip parsing library Dependencies: (optional) Deformat-2.0 ]] local vmajor, vminor = "LibGratuity-3.0", 90000 + tonumber(("$Revision: 42 $"):match("%d+")) local lib = LibStub:NewLibrary(vmajor, vminor) if not lib then return end local methods = { "SetBagItem", "SetAction", "SetAuctionItem", "SetAuctionSellItem", "SetBuybackItem", "SetCraftItem", "SetCraftSpell", "SetHyperlink", "SetInboxItem", "SetInventoryItem", "SetLootItem", "SetLootRollItem", "SetMerchantItem", "SetPetAction", "SetPlayerBuff", "SetQuestItem", "SetQuestLogItem", "SetQuestRewardSpell", "SetSendMailItem", "SetShapeshift", "SetSpellByID", "SetTalent", "SetTrackingSpell", "SetTradePlayerItem", "SetTradeSkillItem", "SetTradeTargetItem", "SetTrainerService", "SetUnit", "SetUnitBuff", "SetUnitDebuff", "SetGuildBankItem", } if select(4, GetBuildInfo()) >= 40000 then table.insert(methods, "SetSpellBookItem") else table.insert(methods, "SetSpell") end function lib:CreateTooltip() local tt = CreateFrame("GameTooltip") self.vars.tooltip = tt tt:SetOwner(UIParent, "ANCHOR_NONE") -- tt:SetOwner(tt, "ANCHOR_NONE") -- tooltip:SetParent() self.vars.Llines, self.vars.Rlines = {}, {} for i=1,30 do self.vars.Llines[i], self.vars.Rlines[i] = tt:CreateFontString(), tt:CreateFontString() self.vars.Llines[i]:SetFontObject(GameFontNormal) self.vars.Rlines[i]:SetFontObject(GameFontNormal) tt:AddFontStrings(self.vars.Llines[i], self.vars.Rlines[i]) end end -- Clears the tooltip completely, none of this "erase left, hide right" crap blizzard does function lib:Erase() self.vars.tooltip:ClearLines() -- Ensures tooltip's NumLines is reset for i=1,30 do self.vars.Rlines[i]:SetText() end -- Clear text from right side (ClearLines only hides them) -- if not self.vars.tooltip:IsOwned(self.vars.tooltip) then self.vars.tooltip:SetOwner(self.vars.tooltip, "ANCHOR_NONE") end if not self.vars.tooltip:IsOwned(UIParent) then self.vars.tooltip:SetOwner(UIParent, "ANCHOR_NONE") end -- if not self.vars.tooltip:IsOwned(self.vars.tooltip) then -- error("Gratuity's tooltip is not scannable", 2) -- end if not self.vars.tooltip:IsOwned(UIParent) then error("Gratuity's tooltip is not scannable", 2) end end -- Get the number of lines -- Arg: endln - If passed and tooltip's NumLines is higher, endln is returned back function lib:NumLines(endln) local num = self.vars.tooltip:NumLines() return endln and num > endln and endln or num or 0 end local FindDefault = function(str, pattern) return string.find(str, pattern); end; local FindExact = function(str, pattern) if (str == pattern) then return string.find(str, pattern); end; end; -- If text is found on tooltip then results of string.find are returned -- Args: -- txt - The text string to find -- startln - First tooltip line to check, default 1 -- endln - Last line to test, default 30 -- ignoreleft / ignoreright - Causes text on one side of the tooltip to be ignored -- exact - the compare will be an exact match vs the default behaviour of function lib:Find(txt, startln, endln, ignoreleft, ignoreright, exact) local searchFunction = FindDefault; if (exact == true) then searchFunction = FindExact; end; assert(type(txt) == "string" or type(txt) == "number") local t1, t2 = type(startln or 1), type(self:NumLines(endln)) if (t1 ~= "number" or t2 ~= "number") then print(t1, t2, (startln or 1),self:NumLines(endln)) end for i=(startln or 1),self:NumLines(endln) do if not ignoreleft and self.vars.Llines[i] then local txtl = self.vars.Llines[i]:GetText() if (txtl and searchFunction(txtl, txt)) then return string.find(txtl, txt) end end if not ignoreright and self.vars.Rlines[i] then local txtr = self.vars.Rlines[i]:GetText() if (txtr and searchFunction(txtr, txt)) then return string.find(txtr, txt) end end end end -- Calls Find many times. -- Args are passed directly to Find, t1-t10 replace the txt arg -- Returns Find results for the first match found, if any function lib:MultiFind(startln, endln, ignoreleft, ignoreright, t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) assert(type(t1) == "string" or type(t1) == "number") if t1 and self:Find(t1, startln, endln, ignoreleft, ignoreright) then return self:Find(t1, startln, endln, ignoreleft, ignoreright) elseif t2 then return self:MultiFind(startln, endln, ignoreleft, ignoreright, t2,t3,t4,t5,t6,t7,t8,t9,t10) end end local deformat -- If text is found on tooltip then results of deformat:Deformat are returned -- Args: -- txt - The text string to deformat and serach for -- startln - First tooltip line to check, default 1 -- endln - Last line to test, default 30 -- ignoreleft / ignoreright - Causes text on one side of the tooltip to be ignored function lib:FindDeformat(txt, startln, endln, ignoreleft, ignoreright) assert(type(txt) == "string" or type(txt) == "number") if not deformat then if not AceLibrary or not AceLibrary:HasInstance("Deformat-2.0") then error("FindDeformat requires Deformat-2.0 to be available", 2) end deformat = AceLibrary("Deformat-2.0") end for i=(startln or 1),self:NumLines(endln) do if not ignoreleft and self.vars.Llines[i] then local txtl = self.vars.Llines[i]:GetText() if (txtl and deformat(txtl, txt)) then return deformat(txtl, txt) end end if not ignoreright and self.vars.Rlines[i] then local txtr = self.vars.Rlines[i]:GetText() if (txtr and deformat(txtr, txt)) then return deformat(txtr, txt) end end end end -- Returns a table of strings pulled from the tooltip, or nil if no strings in tooltip -- Args: -- startln - First tooltip line to check, default 1 -- endln - Last line to test, default 30 -- ignoreleft / ignoreright - Causes text on one side of the tooltip to be ignored function lib:GetText(startln, endln, ignoreleft, ignoreright) local retval for i=(startln or 1),(endln or 30) do local txtl, txtr if not ignoreleft and self.vars.Llines[i] then txtl = self.vars.Llines[i]:GetText() end if not ignoreright and self.vars.Rlines[i] then txtr = self.vars.Rlines[i]:GetText() end if txtl or txtr then if not retval then retval = {} end local t = {txtl, txtr} table.insert(retval, t) end end return retval end -- Returns the text from a specific line (both left and right unless second arg is true) -- Args: -- line - the line number you wish to retrieve -- getright - if passed the right line will be returned, if not the left will be returned function lib:GetLine(line, getright) assert(type(line) == "number") if self.vars.tooltip:NumLines() < line then return end if getright then return self.vars.Rlines[line] and self.vars.Rlines[line]:GetText() elseif self.vars.Llines[line] then return self.vars.Llines[line]:GetText(), self.vars.Rlines[line]:GetText() end end ----------------------------------- -- Set tooltip methods -- ----------------------------------- -- These methods are designed to immitate the GameTooltip API local testmethods = { SetAction = function(id) return HasAction(id) end, } local gettrue = function() return true end local function handlePcall(success, ...) if not success then geterrorhandler()(...) return end return ... end function lib:CreateSetMethods() for _,m in pairs(methods) do local meth = m local func = testmethods[meth] or gettrue self[meth] = function(self, ...) self:Erase() if not func(...) then return end return handlePcall(pcall(self.vars.tooltip[meth], self.vars.tooltip, ...)) end end end -- Activate a new instance of this library if not lib.vars then lib.vars = {} lib:CreateTooltip() end lib:CreateSetMethods() local function createCompat() createCompat = nil local Gratuity20 = setmetatable({}, {__index=function(self, key) if type(lib[key]) == "function" then self[key] = function(self, ...) return lib[key](lib, ...) end else self[key] = lib[key] end return self[key] end}) AceLibrary:Register(Gratuity20, "Gratuity-2.0", vminor+70000000) end if not AceLibrary then local frame = CreateFrame("Frame") frame:RegisterEvent("ADDON_LOADED") frame:SetScript("OnEvent", function(this) if not AceLibrary then return end createCompat() frame:SetScript("OnEvent", nil) frame:UnregisterAllEvents() frame:Hide() end) else createCompat() end