local SLE, T, E, L, V, P, G = unpack(select(2, ...)) local Sk = SLE:GetModule("Skins") local S = E:GetModule('Skins') --GLOBALS: CreateFrame, MERCHANT_ITEMS_PER_PAGE, BUYBACK_ITEMS_PER_PAGE, hooksecurefunc, MERCHANT_PAGE_NUMBER, UIParent, ChatFontSmall local _G = _G local strtrim = strtrim local ItemsPerSubpage, SubpagesPerPage local math_max, math_ceil = math.max, math.ceil local MerchantFrame_UpdateAltCurrency, MoneyFrame_Update = MerchantFrame_UpdateAltCurrency, MoneyFrame_Update local GetMerchantNumItems = GetMerchantNumItems local GetMerchantItemInfo, GetMerchantItemLink = GetMerchantItemInfo, GetMerchantItemLink local SetItemButtonCount, SetItemButtonStock, SetItemButtonTexture = SetItemButtonCount, SetItemButtonStock, SetItemButtonTexture local SetItemButtonNameFrameVertexColor, SetItemButtonSlotVertexColor, SetItemButtonTextureVertexColor, SetItemButtonNormalTextureVertexColor = SetItemButtonNameFrameVertexColor, SetItemButtonSlotVertexColor, SetItemButtonTextureVertexColor, SetItemButtonNormalTextureVertexColor local RETRIEVING_ITEM_INFO, RETRIEVING_ITEM_INFO, MOUNT, ITEM_SPELL_KNOWN, SEARCH = RETRIEVING_ITEM_INFO, RETRIEVING_ITEM_INFO, MOUNT, ITEM_SPELL_KNOWN, SEARCH local MISCELLANEOUS = MISCELLANEOUS local RECIPE = GetItemClassInfo(LE_ITEM_CLASS_RECIPE) local searchBox local searching = "" local IgnoreCurrency = { [T.GetCurrencyInfo(994)] = true, } local function SkinVendorItems(i) local b = _G["MerchantItem"..i.."ItemButton"] local t = _G["MerchantItem"..i.."ItemButtonIconTexture"] local item_bar = _G["MerchantItem"..i] item_bar:StripTextures(true) item_bar:CreateBackdrop("Default") b:StripTextures() b:StyleButton(false) b:SetTemplate("Default", true) b:Point("TOPLEFT", item_bar, "TOPLEFT", 4, -4) t:SetTexCoord(T.unpack(E.TexCoords)) t:SetInside() _G["MerchantItem"..i.."MoneyFrame"]:ClearAllPoints() _G["MerchantItem"..i.."MoneyFrame"]:Point("BOTTOMLEFT", b, "BOTTOMRIGHT", 3, 0) end local function UpdateButtonsPositions(isBuyBack) local btn; local vertSpacing, horizSpacing if (isBuyBack) then vertSpacing = -30 horizSpacing = 50 searchBox:Hide() else vertSpacing = -16 horizSpacing = 12 searchBox:Show() end for i = 1, MERCHANT_ITEMS_PER_PAGE do btn = _G["MerchantItem" .. i] if (isBuyBack) then if (i > BUYBACK_ITEMS_PER_PAGE) then btn:Hide() else if (i == 1) then btn:SetPoint("TOPLEFT", _G["MerchantFrame"], "TOPLEFT", 64, -105) else if ((i % 3) == 1) then btn:SetPoint("TOPLEFT", _G["MerchantItem" .. (i-3)], "BOTTOMLEFT", 0, vertSpacing) else btn:SetPoint("TOPLEFT", _G["MerchantItem" .. (i-1)], "TOPRIGHT", horizSpacing, 0) end end end else btn:Show() if ((i % ItemsPerSubpage) == 1) then if (i == 1) then btn:SetPoint("TOPLEFT", _G["MerchantFrame"], "TOPLEFT", 24, -70) else btn:SetPoint("TOPLEFT", _G["MerchantItem" .. (i-(ItemsPerSubpage - 1))], "TOPRIGHT", 12, 0) end else if ((i % 2) == 1) then btn:SetPoint("TOPLEFT", _G["MerchantItem" .. (i-2)], "BOTTOMLEFT", 0, vertSpacing) else btn:SetPoint("TOPLEFT", _G["MerchantItem" .. (i-1)], "TOPRIGHT", horizSpacing, 0) end end end end end local function UpdateBuybackInfo() if E.private.sle.skins.merchant.style == "Default" then UpdateButtonsPositions(true) end -- apply coloring local btn, link, quality, r, g, b, _; for i = 1, BUYBACK_ITEMS_PER_PAGE, 1 do btn = _G["MerchantItem" .. i]; if (btn) then link = T.GetBuybackItemLink(i); if (link) then _, _, quality = T.GetItemInfo(link); if quality then r, g, b = T.GetItemQualityColor(quality); else r, g, b = 1,1,1 end _G["MerchantItem" .. i .. "Name"]:SetTextColor(r, g, b); end end end end local function isKnown(link, itemType, itemSubType) if ( not link ) then return false; end local upperLimit local isMount = false local isRecipe = false if itemType == RECIPE then isRecipe = true elseif itemType == MISCELLANEOUS and itemSubType == MOUNT then isMount = true end _G["SLE_Merchant_HiddenTooltip"]:SetOwner(UIParent, "ANCHOR_NONE"); _G["SLE_Merchant_HiddenTooltip"]:SetHyperlink(link); upperLimit = isRecipe and _G["SLE_Merchant_HiddenTooltip"]:NumLines() or 0 for i=2, _G["SLE_Merchant_HiddenTooltip"]:NumLines() do if (isRecipe and (i <= 5 or i >= upperLimit - 3)) or isMount or not isRecipe then local text = _G["SLE_Merchant_HiddenTooltipTextLeft"..i]; local r, g, b = text:GetTextColor(); local gettext = text:GetText(); if ( gettext and r >= 0.9 and g <= 0.2 and b <= 0.2 and gettext ~= RETRIEVING_ITEM_INFO ) then if gettext == ITEM_SPELL_KNOWN then return true end end end end return false end local function UpdateMerchantInfo() UpdateButtonsPositions() local totalMerchantItems = GetMerchantNumItems(); local visibleMerchantItems = 0 local indexes = {} local _, name, texture, price, quantity, numAvailable, isUsable, extendedCost, r, g, b, notOptimal; local link, quality, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemSellPrice, itemId; for i = 1, totalMerchantItems do T.tinsert(indexes, i); visibleMerchantItems = visibleMerchantItems + 1; end -- validate current page shown if (_G["MerchantFrame"].page > math_max(1, math_ceil(visibleMerchantItems / MERCHANT_ITEMS_PER_PAGE))) then _G["MerchantFrame"].page = math_max(1, math_ceil(visibleMerchantItems / MERCHANT_ITEMS_PER_PAGE)); end -- Show correct page count based on number of items shown _G["MerchantPageText"]:SetFormattedText(MERCHANT_PAGE_NUMBER, _G["MerchantFrame"].page, math_ceil(visibleMerchantItems / MERCHANT_ITEMS_PER_PAGE)); --Display shit for i = 1, MERCHANT_ITEMS_PER_PAGE do local index = ((_G["MerchantFrame"].page - 1) * MERCHANT_ITEMS_PER_PAGE) + i; local itemButton = _G["MerchantItem" .. i .. "ItemButton"]; itemButton.link = nil; local merchantButton = _G["MerchantItem" .. i]; local merchantMoney = _G["MerchantItem" .. i .. "MoneyFrame"]; local merchantAltCurrency = _G["MerchantItem" .. i .. "AltCurrencyFrame"]; if (index <= visibleMerchantItems) then name, texture, price, quantity, numAvailable, isUsable, extendedCost = GetMerchantItemInfo(indexes[index]); if (name ~= nil) then _G["MerchantItem"..i.."Name"]:SetText(name); SetItemButtonCount(itemButton, quantity); SetItemButtonStock(itemButton, numAvailable); SetItemButtonTexture(itemButton, texture); -- update item's currency info if ( extendedCost and (price <= 0) ) then itemButton.price = nil; itemButton.extendedCost = true; itemButton.link = GetMerchantItemLink(indexes[index]); itemButton.texture = texture; MerchantFrame_UpdateAltCurrency(indexes[index], i); merchantAltCurrency:ClearAllPoints(); merchantAltCurrency:SetPoint("BOTTOMLEFT", "MerchantItem"..i.."NameFrame", "BOTTOMLEFT", 0, 31); merchantMoney:Hide(); merchantAltCurrency:Show(); elseif ( extendedCost and (price > 0) ) then itemButton.price = price; itemButton.extendedCost = true; itemButton.link = GetMerchantItemLink(indexes[index]); itemButton.texture = texture; MerchantFrame_UpdateAltCurrency(indexes[index], i); MoneyFrame_Update(merchantMoney:GetName(), price); merchantAltCurrency:ClearAllPoints(); merchantAltCurrency:SetPoint("LEFT", merchantMoney:GetName(), "RIGHT", -14, 0); merchantAltCurrency:Show(); merchantMoney:Show(); else itemButton.price = price; itemButton.extendedCost = nil; itemButton.link = GetMerchantItemLink(indexes[index]); itemButton.texture = texture; MoneyFrame_Update(merchantMoney:GetName(), price); merchantAltCurrency:Hide(); merchantMoney:Show(); end quality = 1; if (itemButton.link) and not IgnoreCurrency[name] then _, _, quality, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, _, itemSellPrice = T.GetItemInfo(itemButton.link); end -- set color r, g, b = T.GetItemQualityColor(quality); _G["MerchantItem" .. i .. "Name"]:SetTextColor(r, g, b); itemButton.hasItem = true; itemButton:SetID(indexes[index]); itemButton:Show(); local colorMult = 1.0; local detailColor = {}; local slotColor = {}; -- unavailable items (limited stock, bought out) are darkened if ( numAvailable == 0 ) then colorMult = 0.5; end if ( not isUsable ) then slotColor = {r = 1.0, g = 0, b = 0}; detailColor = {r = 1.0, g = 0, b = 0}; else -- print(itemType) if not isKnown(itemButton.link, itemType, itemSubType) then slotColor = {r = 1.0, g = 1.0, b = 1.0}; detailColor = {r = 0.5, g = 0.5, b = 0.5}; else slotColor = {r = 1.0, g = 0, b = 0}; detailColor = {r = 1.0, g = 0, b = 0}; end end local alpha = 0.3; if ( searching == "" or searching == SEARCH:lower() or name:lower():match(searching) or ( quality and ( T.tostring(quality):lower():match(searching) or _G["ITEM_QUALITY"..T.tostring(quality).."_DESC"]:lower():match(searching) ) ) or ( itemType and itemType:lower():match(searching) ) or ( itemSubType and itemSubType:lower():match(searching) ) ) then alpha = 1; end merchantButton:SetAlpha(alpha); SetItemButtonNameFrameVertexColor(merchantButton, detailColor.r * colorMult, detailColor.g * colorMult, detailColor.b * colorMult); SetItemButtonSlotVertexColor(merchantButton, slotColor.r * colorMult, slotColor.g * colorMult, slotColor.b * colorMult); SetItemButtonTextureVertexColor(itemButton, slotColor.r * colorMult, slotColor.g * colorMult, slotColor.b * colorMult); SetItemButtonNormalTextureVertexColor(itemButton, slotColor.r * colorMult, slotColor.g * colorMult, slotColor.b * colorMult); end else itemButton.price = nil; itemButton.hasItem = nil; itemButton:Hide(); SetItemButtonNameFrameVertexColor(merchantButton, 0.5, 0.5, 0.5); SetItemButtonSlotVertexColor(merchantButton,0.4, 0.4, 0.4); _G["MerchantItem"..i.."Name"]:SetText(""); _G["MerchantItem"..i.."MoneyFrame"]:Hide(); _G["MerchantItem"..i.."AltCurrencyFrame"]:Hide(); end end end local function RebuildMerchantFrame() ItemsPerSubpage = MERCHANT_ITEMS_PER_PAGE SubpagesPerPage = E.private.sle.skins.merchant.subpages MERCHANT_ITEMS_PER_PAGE = SubpagesPerPage * 10 --Haven't seen this causing any taints so I asume it's ok _G["MerchantFrame"]:SetWidth(42 + (318 * SubpagesPerPage) + (12 * (SubpagesPerPage - 1))) for i = 1, MERCHANT_ITEMS_PER_PAGE do if (not _G["MerchantItem" .. i]) then CreateFrame("Frame", "MerchantItem" .. i, _G["MerchantFrame"], "MerchantItemTemplate") SkinVendorItems(i) end end -- alter the position of the buyback item slot on the merchant tab _G["MerchantBuyBackItem"]:ClearAllPoints() _G["MerchantBuyBackItem"]:SetPoint("TOPLEFT", _G["MerchantItem10"], "BOTTOMLEFT", -14, -20) -- move the next/previous page buttons _G["MerchantPrevPageButton"]:ClearAllPoints(); _G["MerchantPrevPageButton"]:SetPoint("CENTER", _G["MerchantFrame"], "BOTTOM", 50, 70); _G["MerchantPageText"]:ClearAllPoints(); _G["MerchantPageText"]:SetPoint("BOTTOM", _G["MerchantFrame"], "BOTTOM", 160, 65); _G["MerchantNextPageButton"]:ClearAllPoints(); _G["MerchantNextPageButton"]:SetPoint("CENTER", _G["MerchantFrame"], "BOTTOM", 270, 70); -- currency insets _G["MerchantExtraCurrencyInset"]:ClearAllPoints(); _G["MerchantExtraCurrencyInset"]:SetPoint("BOTTOMRIGHT", _G["MerchantMoneyInset"], "BOTTOMLEFT", 0, 0); _G["MerchantExtraCurrencyInset"]:SetPoint("TOPLEFT", _G["MerchantMoneyInset"], "TOPLEFT", -165, 0); _G["MerchantExtraCurrencyBg"]:ClearAllPoints(); _G["MerchantExtraCurrencyBg"]:SetPoint("TOPLEFT", _G["MerchantExtraCurrencyInset"], "TOPLEFT", 3, -2); _G["MerchantExtraCurrencyBg"]:SetPoint("BOTTOMRIGHT", _G["MerchantExtraCurrencyInset"], "BOTTOMRIGHT", -3, 2); searchBox = CreateFrame("EditBox", "$parentSearchBox", _G["MerchantFrame"], "InputBoxTemplate"); searchBox:SetWidth(_G["MerchantItem1"]:GetWidth()); searchBox:SetHeight(24); searchBox:SetPoint("BOTTOMLEFT", _G["MerchantItem1"], "TOPLEFT", 0, 9); searchBox:SetAutoFocus(false); searchBox:SetFontObject(ChatFontSmall); searchBox:SetScript("OnTextChanged", function(self) searching = self:GetText():trim():lower(); UpdateMerchantInfo() end) searchBox:SetScript("OnShow", function(self) self:SetText(SEARCH); searching = "" end) searchBox:SetScript("OnEnterPressed", function(self) self:ClearFocus() end) searchBox:SetScript("OnEscapePressed", function(self) self:ClearFocus(); self:SetText(SEARCH); searching = "" end) searchBox:SetScript("OnEditFocusLost", function(self) self:HighlightText(0, 0); if ( strtrim(self:GetText()) == "" ) then self:SetText(SEARCH); searching = ""; end end) searchBox:SetScript("OnEditFocusGained", function(self) self:HighlightText(); if ( self:GetText():trim():lower() == SEARCH:lower() ) then self:SetText(""); end end) searchBox:SetText(SEARCH); S:HandleEditBox(searchBox) end local function MerchantSkinInit() if E.private.skins.blizzard.enable ~= true or E.private.skins.blizzard.merchant ~= true or E.private.sle.skins.merchant.enable ~= true then return end hooksecurefunc("MerchantFrame_UpdateBuybackInfo", UpdateBuybackInfo) if E.private.sle.skins.merchant.style ~= "Default" then return end RebuildMerchantFrame() UpdateButtonsPositions() CreateFrame("GameTooltip", "SLE_Merchant_HiddenTooltip", UIParent, "GameTooltipTemplate"); hooksecurefunc("MerchantFrame_UpdateMerchantInfo", UpdateMerchantInfo) end hooksecurefunc(S, "Initialize", MerchantSkinInit)