local SLE, T, E, L, V, P, G = unpack(ElvUI_SLE) local Sk = SLE.Skins local S = E.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 C_CurrencyInfo_GetCurrencyInfo = C_CurrencyInfo.GetCurrencyInfo local C_Item_GetItemInfo = C_Item.GetItemInfo local RETRIEVING_ITEM_INFO, MOUNT, ITEM_SPELL_KNOWN, SEARCH = RETRIEVING_ITEM_INFO, MOUNT, ITEM_SPELL_KNOWN, SEARCH local MISCELLANEOUS = MISCELLANEOUS local MAX_MONEY_DISPLAY_WIDTH = 120 local RECIPE = C_Item.GetItemClassInfo(Enum.ItemClass.Recipe) local searchBox local searching = '' local function SkinVendorItems(i) local item = _G['MerchantItem'..i] item:Size(155, 45) item:StripTextures(true) item:CreateBackdrop('Transparent') item.backdrop:Point('TOPLEFT', -3, 2) item.backdrop:Point('BOTTOMRIGHT', 2, -3) local slot = _G['MerchantItem'..i..'SlotTexture'] item.Name:Point('LEFT', slot, 'RIGHT', -5, 5) item.Name:Size(110, 30) local button = _G['MerchantItem'..i..'ItemButton'] button:StripTextures() button:StyleButton() button:SetTemplate(nil, true) button:Point('TOPLEFT', item, 'TOPLEFT', 4, -4) local icon = button.icon icon:SetTexCoord(unpack(E.TexCoords)) icon:ClearAllPoints() icon:Point('TOPLEFT', 1, -1) icon:Point('BOTTOMRIGHT', -1, 1) S:HandleIconBorder(button.IconBorder) _G['MerchantItem'..i..'MoneyFrame']:ClearAllPoints() _G['MerchantItem'..i..'MoneyFrame']:Point('BOTTOMLEFT', button, 'BOTTOMRIGHT', 3, 0) MerchantBuyBackItemItemButton.IconBorder:SetAlpha(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 = GetBuybackItemLink(i) if (link) then _, _, quality = C_Item_GetItemInfo(link) if quality then r, g, b = 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 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, isPurchasable, isUsable, extendedCost = GetMerchantItemInfo(indexes[index]) if (name ~= nil) then local canAfford = CanAffordMerchantItem(index) _G['MerchantItem'..i..'Name']:SetText(name) SetItemButtonCount(itemButton, quantity) SetItemButtonStock(itemButton, numAvailable) SetItemButtonTexture(itemButton, texture) if (extendedCost and (price <= 0)) then -- update item's currency info itemButton.price = nil itemButton.extendedCost = true itemButton.name = name itemButton.link = GetMerchantItemLink(indexes[index]) itemButton.texture = texture MerchantFrame_UpdateAltCurrency(index, i, canAfford) 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.name = name itemButton.link = GetMerchantItemLink(indexes[index]) itemButton.texture = texture local altCurrencyWidth = MerchantFrame_UpdateAltCurrency(index, i, canAfford) MoneyFrame_SetMaxDisplayWidth(merchantMoney, MAX_MONEY_DISPLAY_WIDTH - altCurrencyWidth) MoneyFrame_Update(merchantMoney:GetName(), price) local color if (canAfford == false) then color = 'red' end SetMoneyFrameColor(merchantMoney:GetName(), color) merchantAltCurrency:ClearAllPoints() merchantAltCurrency:SetPoint('LEFT', merchantMoney:GetName(), 'RIGHT', -14, 0) merchantAltCurrency:Show() merchantMoney:Show() else itemButton.price = price itemButton.extendedCost = nil itemButton.name = name itemButton.link = GetMerchantItemLink(indexes[index]) itemButton.texture = texture MoneyFrame_SetMaxDisplayWidth(merchantMoney, MAX_MONEY_DISPLAY_WIDTH) MoneyFrame_Update(merchantMoney:GetName(), price) local color if (canAfford == false) then color = 'red' end SetMoneyFrameColor(merchantMoney:GetName(), color) merchantAltCurrency:Hide() merchantMoney:Show() end MerchantFrameItem_UpdateQuality(merchantButton, itemButton.link) local merchantItemID = GetMerchantItemID(index) local isHeirloom = merchantItemID and C_Heirloom.IsItemHeirloom(merchantItemID) local isKnownHeirloom = isHeirloom and C_Heirloom.PlayerHasHeirloom(merchantItemID) itemButton.showNonrefundablePrompt = isHeirloom itemButton.hasItem = true itemButton:SetID(indexes[index]) itemButton:Show() local tintRed = not isPurchasable or (not isUsable and not isHeirloom) local colorMult = 1.0 local detailColor = {} local slotColor = {} -- unavailable items (limited stock, bought out) are darkened if ( numAvailable == 0 or isKnownHeirloom) then colorMult = 0.5 end if ( tintRed ) then slotColor = {r = 1.0, g = 0, b = 0} detailColor = {r = 1.0, g = 0, b = 0} else 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 ( tostring(quality):lower():match(searching) or _G["ITEM_QUALITY"..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.name = 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)