-- Shopkeeper UI Functions File -- Last Updated August 10, 2014 -- Written August 2014 by Dan Stone (@khaibit) - dankitymao@gmail.com -- Released under terms in license accompanying this file. -- Distribution without license is prohibited! -- Handle the OnMoveStop event for the windows function Shopkeeper.OnWindowMoveStop() Shopkeeper.savedVariables.winLeft = ShopkeeperWindow:GetLeft() Shopkeeper.savedVariables.winTop = ShopkeeperWindow:GetTop() Shopkeeper.savedVariables.miniWinLeft = ShopkeeperMiniWindow:GetLeft() Shopkeeper.savedVariables.miniWinTop = ShopkeeperMiniWindow:GetTop() end function Shopkeeper.OnStatsWindowMoveStop() Shopkeeper.savedVariables.statsWinLeft = ShopkeeperStatsWindow:GetLeft() Shopkeeper.savedVariables.statsWinTop = ShopkeeperStatsWindow:GetTop() end -- Restore the window positions from saved vars function Shopkeeper:RestoreWindowPosition() local left = self.savedVariables.winLeft local top = self.savedVariables.winTop local statsLeft = self.savedVariables.statsWinLeft local statsTop = self.savedVariables.statsWinTop local miniLeft = self.savedVariables.miniWinLeft local miniTop = self.savedVariables.miniWinTop ShopkeeperWindow:ClearAnchors() ShopkeeperStatsWindow:ClearAnchors() ShopkeeperMiniWindow:ClearAnchors() ShopkeeperWindow:SetAnchor(TOPLEFT, GuiRoot, TOPLEFT, left, top) ShopkeeperStatsWindow:SetAnchor(TOPLEFT, GuiRoot, TOPLEFT, statsLeft, statsTop) ShopkeeperMiniWindow:SetAnchor(TOPLEFT, GuiRoot, TOPLEFT, miniLeft, miniTop) end -- Handle the changing of window font settings function Shopkeeper:UpdateFonts() local LMP = LibStub("LibMediaProvider-1.0") if LMP then local font = LMP:Fetch('font', Shopkeeper.savedVariables.windowFont) local fontString = font .. "|%d" ShopkeeperWindowSearchLabel:SetFont(string.format(fontString, 16)) ShopkeeperWindowSearchBox:SetFont(string.format(fontString, 16)) ShopkeeperWindowTitle:SetFont(string.format(fontString, 26)) ShopkeeperWindowBuyer:SetFont(string.format(fontString, 20)) ShopkeeperWindowGuild:SetFont(string.format(fontString, 20)) ShopkeeperWindowItemName:SetFont(string.format(fontString, 20)) ShopkeeperWindowSellTime:SetFont(string.format(fontString, 20)) ShopkeeperWindowPrice:SetFont(string.format(fontString, 20)) ShopkeeperSwitchViewButton:SetFont(string.format(fontString, 16)) ShopkeeperPriceSwitchButton:SetFont(string.format(fontString, 16)) ShopkeeperResetButton:SetFont(string.format(fontString, 16)) ShopkeeperRefreshButton:SetFont(string.format(fontString, 16)) ShopkeeperMiniWindowSearchLabel:SetFont(string.format(fontString, 12)) ShopkeeperMiniWindowSearchBox:SetFont(string.format(fontString, 12)) ShopkeeperMiniWindowTitle:SetFont(string.format(fontString, 20)) ShopkeeperMiniWindowGuild:SetFont(string.format(fontString, 16)) ShopkeeperMiniWindowItemName:SetFont(string.format(fontString, 16)) ShopkeeperMiniWindowSellTime:SetFont(string.format(fontString, 16)) ShopkeeperMiniWindowPrice:SetFont(string.format(fontString, 16)) ShopkeeperMiniSwitchViewButton:SetFont(string.format(fontString, 12)) ShopkeeperMiniPriceSwitchButton:SetFont(string.format(fontString, 12)) ShopkeeperMiniResetButton:SetFont(string.format(fontString, 12)) ShopkeeperMiniRefreshButton:SetFont(string.format(fontString, 12)) ShopkeeperStatsWindowTitle:SetFont(string.format(fontString, 26)) ShopkeeperStatsWindowItemsSoldLabel:SetFont(string.format(fontString, 18)) ShopkeeperStatsWindowTotalGoldLabel:SetFont(string.format(fontString, 18)) ShopkeeperStatsWindowBiggestSaleLabel:SetFont(string.format(fontString, 18)) ShopkeeperStatsWindowSliderSettingLabel:SetFont(string.format(fontString, 18)) ShopkeeperStatsWindowSliderLabel:SetFont(string.format(fontString, 16)) for i = 1, #Shopkeeper.DataRows do local dataRow = Shopkeeper.DataRows[i] dataRow:GetNamedChild("Buyer"):SetFont(string.format(fontString, 16)) dataRow:GetNamedChild("Guild"):SetFont(string.format(fontString, 16)) dataRow:GetNamedChild("ItemName"):SetFont(string.format(fontString, 16)) dataRow:GetNamedChild("Quantity"):SetFont(string.format(fontString, 16)) dataRow:GetNamedChild("SellTime"):SetFont(string.format(fontString, 16)) dataRow:GetNamedChild("Price"):SetFont(string.format(fontString, 16)) if i <= #Shopkeeper.MiniDataRows then local miniDataRow = Shopkeeper.MiniDataRows[i] miniDataRow:GetNamedChild("Guild"):SetFont(string.format(fontString, 12)) miniDataRow:GetNamedChild("ItemName"):SetFont(string.format(fontString, 12)) miniDataRow:GetNamedChild("Quantity"):SetFont(string.format(fontString, 12)) miniDataRow:GetNamedChild("SellTime"):SetFont(string.format(fontString, 12)) miniDataRow:GetNamedChild("Price"):SetFont(string.format(fontString, 12)) end end end end -- Item tooltips function Shopkeeper:ShowToolTip(itemName, itemButton) InitializeTooltip(ItemTooltip, itemButton) ItemTooltip:SetLink(itemName) end -- Clear a given row's data function Shopkeeper.ClearDataRow(index) if index < 1 or index > 15 then return end local dataRow = Shopkeeper.DataRows[index] dataRow:GetNamedChild("Buyer"):SetText("") dataRow:GetNamedChild("Buyer"):SetHandler("OnMouseDoubleClick", nil) dataRow:GetNamedChild("Guild"):SetText("") dataRow:GetNamedChild("ItemIcon"):SetTexture(nil) dataRow:GetNamedChild("ItemIcon"):SetHidden(true) local itemCell = dataRow:GetNamedChild("ItemName") itemCell:SetText("") itemCell:SetHandler("OnMouseDoubleClick", nil) itemCell:SetHandler("OnMouseEnter", nil) dataRow:GetNamedChild("Quantity"):SetText("") dataRow:GetNamedChild("SellTime"):SetText("") dataRow:GetNamedChild("Price"):SetText("") end function Shopkeeper.ClearMiniDataRow(index) if index < 1 or index > 8 then return end local dataRow = Shopkeeper.MiniDataRows[index] dataRow:GetNamedChild("Guild"):SetText("") dataRow:GetNamedChild("ItemIcon"):SetTexture(nil) dataRow:GetNamedChild("ItemIcon"):SetHidden(true) local itemCell = dataRow:GetNamedChild("ItemName") itemCell:SetText("") itemCell:SetHandler("OnMouseDoubleClick", nil) itemCell:SetHandler("OnMouseEnter", nil) dataRow:GetNamedChild("Quantity"):SetText("") dataRow:GetNamedChild("SellTime"):SetText("") dataRow:GetNamedChild("Price"):SetText("") end -- Fill out a row with the given data function Shopkeeper.SetDataRow(index, buyer, guild, itemName, icon, quantity, sellTime, price, seller, kioskSale) if index < 1 or index > 15 then return end local dataRow = Shopkeeper.DataRows[index] -- Some extra stuff for the Buyer cell to handle double-click and color changes -- Plus add a marker if buyer is not in-guild (kiosk sale) local buyerCell = dataRow:GetNamedChild("Buyer") local buyerString = buyer if kioskSale ~= nil and kioskSale == true then buyerString = "|t16:16:/EsoUI/Art/icons/item_generic_coinbag.dds|t" .. buyerString end buyerCell:SetText(buyerString) -- If the seller is the player, color the buyer green. Otherwise, blue. local acctName = GetDisplayName() if seller == acctName then buyerCell:SetNormalFontColor(0.18, 0.77, 0.05, 1) buyerCell:SetPressedFontColor(0.18, 0.77, 0.05, 1) buyerCell:SetMouseOverFontColor(0.32, 0.90, 0.18, 1) else buyerCell:SetNormalFontColor(0.21, 0.54, 0.94, 1) buyerCell:SetPressedFontColor(0.21, 0.54, 0.94, 1) buyerCell:SetMouseOverFontColor(0.34, 0.67, 1, 1) end buyerCell:SetHandler("OnMouseDoubleClick", function() if SCENE_MANAGER.currentScene.name == "mailSend" then ZO_MailSendToField:SetText("") ZO_MailSendToField:SetText(ZO_MailSendToField:GetText() .. buyer) else ZO_ChatWindowTextEntryEditBox:SetText("/w " .. buyer .. " " .. ZO_ChatWindowTextEntryEditBox:GetText()) end end) local buyerCellLabel = buyerCell:GetLabelControl() buyerCellLabel:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS) -- Guild cell dataRow:GetNamedChild("Guild"):SetText(guild) local guildCellLabel = dataRow:GetNamedChild("Guild"):GetLabelControl() guildCellLabel:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS) -- Item Icon dataRow:GetNamedChild("ItemIcon"):SetHidden(false) dataRow:GetNamedChild("ItemIcon"):SetTexture(icon) -- Item name cell local itemCell = dataRow:GetNamedChild("ItemName") itemCell:SetText(zo_strformat("<<t:1>>", itemName)) -- Insert the item link into the chat box, with a quick substitution so brackets show up itemCell:SetHandler("OnMouseDoubleClick", function() ZO_ChatWindowTextEntryEditBox:SetText(ZO_ChatWindowTextEntryEditBox:GetText() .. string.gsub(itemName, "|H0", "|H1")) end) itemCell:SetHandler("OnMouseEnter", function() Shopkeeper:ShowToolTip(itemName, itemCell) end) itemCell:SetHandler("OnMouseExit", function() ClearTooltip(ItemTooltip) end) local itemCellLabel = itemCell:GetLabelControl() itemCellLabel:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS) -- Quantity cell dataRow:GetNamedChild("Quantity"):SetText("x" .. quantity) -- Sale time cell dataRow:GetNamedChild("SellTime"):SetText(sellTime) -- Handle the setting of whether or not to show pre-cut sale prices -- math.floor(number + 0.5) is a quick shorthand way to round for -- positive values. local dispPrice = price if Shopkeeper.savedVariables.showFullPrice then if Shopkeeper.savedVariables.showUnitPrice and quantity > 0 then dispPrice = math.floor((dispPrice / quantity) + 0.5) end else local cutPrice = price * (1 - (GetTradingHouseCutPercentage() / 100)) if Shopkeeper.savedVariables.showUnitPrice and quantity > 0 then cutPrice = cutPrice / quantity end dispPrice = math.floor(cutPrice + 0.5) end -- Insert thousands separators for the price local stringPrice = Shopkeeper.localizedNumber(dispPrice) -- Finally, set the price dataRow:GetNamedChild("Price"):SetText(stringPrice .. " " .. string.format("|t16:16:%s|t","EsoUI/Art/currency/currency_gold.dds")) end -- Fill out a row with the given data function Shopkeeper.SetMiniDataRow(index, guild, itemName, icon, quantity, sellTime, price, seller) if index < 1 or index > 8 then return end local dataRow = Shopkeeper.MiniDataRows[index] -- Guild cell dataRow:GetNamedChild("Guild"):SetText(guild) local guildCellLabel = dataRow:GetNamedChild("Guild"):GetLabelControl() guildCellLabel:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS) -- Item Icon dataRow:GetNamedChild("ItemIcon"):SetHidden(false) dataRow:GetNamedChild("ItemIcon"):SetTexture(icon) -- Item name cell local itemCell = dataRow:GetNamedChild("ItemName") itemCell:SetText(zo_strformat("<<t:1>>", itemName)) -- Insert the item link into the chat box, with a quick substitution so brackets show up itemCell:SetHandler("OnMouseDoubleClick", function() ZO_ChatWindowTextEntryEditBox:SetText(ZO_ChatWindowTextEntryEditBox:GetText() .. string.gsub(itemName, "|H0", "|H1")) end) itemCell:SetHandler("OnMouseEnter", function() Shopkeeper:ShowToolTip(itemName, itemCell) end) itemCell:SetHandler("OnMouseExit", function() ClearTooltip(ItemTooltip) end) local itemCellLabel = itemCell:GetLabelControl() itemCellLabel:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS) -- Quantity cell dataRow:GetNamedChild("Quantity"):SetText("x" .. quantity) -- Sale time cell dataRow:GetNamedChild("SellTime"):SetText(sellTime) -- Handle the setting of whether or not to show pre-cut sale prices -- math.floor(number + 0.5) is a quick shorthand way to round for -- positive values. local dispPrice = price if Shopkeeper.savedVariables.showFullPrice then if Shopkeeper.savedVariables.showUnitPrice and quantity > 0 then dispPrice = math.floor((dispPrice / quantity) + 0.5) end else local cutPrice = price * (1 - (GetTradingHouseCutPercentage() / 100)) if Shopkeeper.savedVariables.showUnitPrice and quantity > 0 then cutPrice = cutPrice / quantity end dispPrice = math.floor(cutPrice + 0.5) end -- Insert thousands separators for the price local stringPrice = Shopkeeper.localizedNumber(dispPrice) -- Finally, set the price dataRow:GetNamedChild("Price"):SetText(stringPrice .. " " .. string.format("|t16:16:%s|t","EsoUI/Art/currency/currency_gold.dds")) end -- Build the data rows based on the position of the slider function Shopkeeper.DisplayRows() if Shopkeeper.savedVariables.viewSize == "full" then local startIndex = ShopkeeperWindowSlider:GetValue() if startIndex + #Shopkeeper.DataRows > #Shopkeeper.SearchTable then startIndex = #Shopkeeper.SearchTable - #Shopkeeper.DataRows end if startIndex < 1 then startIndex = 0 end -- Hide the slider if there's less than a full page of results ShopkeeperWindowSlider:SetHidden(#Shopkeeper.SearchTable < 16) for i = 1, #Shopkeeper.DataRows do local rowIndex = i + startIndex if rowIndex > #Shopkeeper.SearchTable then Shopkeeper.ClearDataRow(i) ShopkeeperWindowSlider:SetHidden(true) else local scanResult = Shopkeeper.SearchTable[rowIndex] -- Older data won't have kiosk info local kioskSale = nil if #scanResult > 8 then kioskSale = scanResult[9] end Shopkeeper.SetDataRow(i, scanResult[1], scanResult[2], scanResult[3], scanResult[4], scanResult[5], Shopkeeper.textTimeSince(scanResult[6], false), scanResult[7], scanResult[8], kioskSale) end end -- Scale the slider's range to the number of items we have minus the number of rows local sliderMax = 0 local tableToUse = Shopkeeper.ScanResults if Shopkeeper.viewMode == "self" then tableToUse = Shopkeeper.SelfSales end if #tableToUse > 15 then sliderMax = (#tableToUse - 15) end ShopkeeperWindowSlider:SetMinMax(0, sliderMax) else local startIndex = ShopkeeperMiniWindowSlider:GetValue() if startIndex + #Shopkeeper.MiniDataRows > #Shopkeeper.SearchTable then startIndex = #Shopkeeper.SearchTable - #Shopkeeper.MiniDataRows end if startIndex < 1 then startIndex = 0 end -- Hide the slider if there's less than a full page of results ShopkeeperMiniWindowSlider:SetHidden(#Shopkeeper.SearchTable < 9) for i = 1, #Shopkeeper.MiniDataRows do local rowIndex = i + startIndex if rowIndex > #Shopkeeper.SearchTable then Shopkeeper.ClearMiniDataRow(i) ShopkeeperMiniWindowSlider:SetHidden(true) else local scanResult = Shopkeeper.SearchTable[rowIndex] Shopkeeper.SetMiniDataRow(i, scanResult[2], scanResult[3], scanResult[4], scanResult[5], Shopkeeper.textTimeSince(scanResult[6], false), scanResult[7], scanResult[8]) end end -- Scale the slider's range to the number of items we have minus the number of rows local sliderMax = 0 local tableToUse = Shopkeeper.ScanResults if Shopkeeper.viewMode == "self" then tableToUse = Shopkeeper.SelfSales end if #tableToUse > 8 then sliderMax = (#tableToUse - 8) end ShopkeeperMiniWindowSlider:SetMinMax(0, sliderMax) end end function Shopkeeper.ToggleViewMode() if Shopkeeper.savedVariables.viewSize == "full" then Shopkeeper.savedVariables.viewSize = "half" ShopkeeperWindow:SetHidden(true) Shopkeeper.DisplayRows() ShopkeeperMiniWindow:SetHidden(false) if Shopkeeper.savedVariables.openWithMail then MAIL_INBOX_SCENE:RemoveFragment(Shopkeeper.uiFragment) MAIL_SEND_SCENE:RemoveFragment(Shopkeeper.uiFragment) MAIL_INBOX_SCENE:AddFragment(Shopkeeper.miniUiFragment) MAIL_SEND_SCENE:AddFragment(Shopkeeper.miniUiFragment) end if Shopkeeper.savedVariables.openWithStore then TRADING_HOUSE_SCENE:RemoveFragment(Shopkeeper.uiFragment) TRADING_HOUSE_SCENE:AddFragment(Shopkeeper.miniUiFragment) end else Shopkeeper.savedVariables.viewSize = "full" ShopkeeperMiniWindow:SetHidden(true) Shopkeeper.DisplayRows() ShopkeeperWindow:SetHidden(false) if Shopkeeper.savedVariables.openWithMail then MAIL_INBOX_SCENE:RemoveFragment(Shopkeeper.miniUiFragment) MAIL_SEND_SCENE:RemoveFragment(Shopkeeper.miniUiFragment) MAIL_INBOX_SCENE:AddFragment(Shopkeeper.uiFragment) MAIL_SEND_SCENE:AddFragment(Shopkeeper.uiFragment) end if Shopkeeper.savedVariables.openWithStore then TRADING_HOUSE_SCENE:RemoveFragment(Shopkeeper.miniUiFragment) TRADING_HOUSE_SCENE:AddFragment(Shopkeeper.uiFragment) end end end -- Set the visibility status of the main window to the opposite of its current status function Shopkeeper.ToggleShopkeeperWindow() if Shopkeeper.savedVariables.viewSize == "full" then ShopkeeperMiniWindow:SetHidden(true) if ShopkeeperWindow:IsHidden() then Shopkeeper.DisplayRows() SetGameCameraUIMode(true) end ShopkeeperWindow:SetHidden(not ShopkeeperWindow:IsHidden()) else ShopkeeperWindow:SetHidden(true) if ShopkeeperMiniWindow:IsHidden() then Shopkeeper.DisplayRows() SetGameCameraUIMode(true) end ShopkeeperMiniWindow:SetHidden(not ShopkeeperMiniWindow:IsHidden()) end end -- Set the visibility status of the stats window to the opposite of its current status function Shopkeeper.ToggleShopkeeperStatsWindow() if ShopkeeperStatsWindow:IsHidden() then Shopkeeper.UpdateStatsWindow() end ShopkeeperStatsWindow:SetHidden(not ShopkeeperStatsWindow:IsHidden()) end -- Handle scrolling the main window function Shopkeeper.OnSliderMouseWheel(self, delta) if Shopkeeper.savedVariables.viewSize == "full" then local oldSliderLevel = ShopkeeperWindowSlider:GetValue() local newSliderLevel = oldSliderLevel - delta ShopkeeperWindowSlider:SetValue(newSliderLevel) else local oldSliderLevel = ShopkeeperMiniWindowSlider:GetValue() local newSliderLevel = oldSliderLevel - delta ShopkeeperMiniWindowSlider:SetValue(newSliderLevel) end end -- Update the table if the slider moved function Shopkeeper.OnSliderMoved(self, sliderLevel, eventReason) Shopkeeper.DisplayRows() end function Shopkeeper.OnStatsSliderMoved(self, sliderLevel, eventReason) Shopkeeper.UpdateStatsWindow() end