Files
TurtleMail/Postal.lua
T
Manuel Simon Hirsig 97f5060a72 small fix
2016-03-14 12:10:54 +01:00

642 lines
18 KiB
Lua

Postal = AceLibrary("AceAddon-2.0"):new("AceEvent-2.0", "AceHook-2.0")
function Postal:OnInitialize()
-- Allows the mail frame to be pushed
if UIPanelWindows["MailFrame"] then
UIPanelWindows["MailFrame"].pushable = 1
else
UIPanelWindows["MailFrame"] = { area = "left", pushable = 1 }
end
-- Close FriendsFrame will close if you try to open a mail with mailframe+friendsframe open
if UIPanelWindows["FriendsFrame"] then
UIPanelWindows["FriendsFrame"].pushable = 2
else
UIPanelWindows["FriendsFrame"] = { area = "left", pushable = 2 }
end
MailItem1:SetPoint("TOPLEFT", "InboxFrame", "TOPLEFT", 48, -80)
for i=1,7 do
getglobal("MailItem" .. i .. "ExpireTime"):SetPoint("TOPRIGHT", "MailItem" .. i, "TOPRIGHT", 10, -4)
getglobal("MailItem" .. i):SetWidth(280)
end
ATTACHMENTS_MAX = 21
ATTACHMENTS_PER_ROW_SEND = 7
ATTACHMENTS_MAX_ROWS_SEND = 3
Postal_SelectedItems = {}
PostalTooltip:SetOwner(WorldFrame, 'ANCHOR_NONE')
end
function Postal:SendMailFrame_Update()
MoneyFrame_Update('SendMailCostMoneyFrame', GetSendMailPrice() * max(1, self:GetNumMails()))
local itemCount = 0
local itemTitle
local gap
-- local last = 0
local last = self:GetNumMails()
for i=1,ATTACHMENTS_MAX do
local btn = getglobal('PostalAttachment' .. i)
local texture, count
if btn.bag and btn.slot then
texture, count = GetContainerItemInfo(btn.bag, btn.slot)
end
if not texture then
btn:SetNormalTexture(nil)
getglobal(btn:GetName()..'Count'):Hide()
btn.slot = nil
btn.bag = nil
else
btn:SetNormalTexture(texture)
if count > 1 then
getglobal(btn:GetName()..'Count'):Show()
getglobal(btn:GetName()..'Count'):SetText(count)
else
getglobal(btn:GetName()..'Count'):Hide()
end
end
end
-- Determine how many rows of attachments to show
local itemRowCount = 1
local temp = last
while temp > ATTACHMENTS_PER_ROW_SEND and itemRowCount < ATTACHMENTS_MAX_ROWS_SEND do
itemRowCount = itemRowCount + 1;
temp = temp - ATTACHMENTS_PER_ROW_SEND
end
if not gap and temp == ATTACHMENTS_PER_ROW_SEND and itemRowCount < ATTACHMENTS_MAX_ROWS_SEND then
itemRowCount = itemRowCount + 1;
end
if SendMailFrame.maxRowsShown and last > 0 and itemRowCount < SendMailFrame.maxRowsShown then
itemRowCount = SendMailFrame.maxRowsShown
else
SendMailFrame.maxRowsShown = itemRowCount
end
-- Compute sizes
local cursorx = 0
local cursory = itemRowCount - 1
local marginxl = 8 + 6
local marginxr = 40 + 6
local areax = SendMailFrame:GetWidth() - marginxl - marginxr
local iconx = PostalAttachment1:GetWidth() + 2
local icony = PostalAttachment1:GetHeight() + 2
local gapx1 = floor((areax - (iconx * ATTACHMENTS_PER_ROW_SEND)) / (ATTACHMENTS_PER_ROW_SEND - 1))
local gapx2 = floor((areax - (iconx * ATTACHMENTS_PER_ROW_SEND) - (gapx1 * (ATTACHMENTS_PER_ROW_SEND - 1))) / 2)
local gapy1 = 5
local gapy2 = 6
local areay = (gapy2 * 2) + (gapy1 * (itemRowCount - 1)) + (icony * itemRowCount)
local indentx = marginxl + gapx2 + 17
local indenty = 170 + gapy2 + icony - 13
local tabx = (iconx + gapx1) - 3 --this magic number changes the attachment spacing
local taby = (icony + gapy1)
local scrollHeight = 249 - areay
PostalHorizontalBarLeft:SetPoint('TOPLEFT', SendMailFrame, 'BOTTOMLEFT', 2 + 15, 184 + areay - 14)
SendMailScrollFrame:SetHeight(scrollHeight)
SendMailScrollChildFrame:SetHeight(scrollHeight)
local SendMailScrollFrameTop = ({SendMailScrollFrame:GetRegions()})[3]
SendMailScrollFrameTop:SetHeight(scrollHeight)
SendMailScrollFrameTop:SetTexCoord(0, 0.484375, 0, scrollHeight / 256)
StationeryBackgroundLeft:SetHeight(scrollHeight)
StationeryBackgroundLeft:SetTexCoord(0, 1.0, 0, scrollHeight / 256)
StationeryBackgroundRight:SetHeight(scrollHeight)
StationeryBackgroundRight:SetTexCoord(0, 1.0, 0, scrollHeight / 256)
-- Set Items
for i=1,ATTACHMENTS_MAX do
if cursory >= 0 then
getglobal("PostalAttachment"..i):Enable()
getglobal("PostalAttachment"..i):Show()
getglobal("PostalAttachment"..i):SetPoint("TOPLEFT", "SendMailFrame", "BOTTOMLEFT", indentx + (tabx * cursorx), indenty + (taby * cursory));
cursorx = cursorx + 1
if cursorx >= ATTACHMENTS_PER_ROW_SEND then
cursory = cursory - 1
cursorx = 0
end
else
getglobal("PostalAttachment"..i):Hide()
end
end
for i=ATTACHMENTS_MAX+1,ATTACHMENTS_MAX do
getglobal("PostalAttachment"..i):Hide()
end
if self:GetNumMails() > 0 then
SendMailCODButton:Enable();
SendMailCODButtonText:SetTextColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b);
else
SendMailRadioButton_OnClick(1);
SendMailCODButton:Disable();
SendMailCODButtonText:SetTextColor(GRAY_FONT_COLOR.r, GRAY_FONT_COLOR.g, GRAY_FONT_COLOR.b);
end
Postal:SendMailFrame_CanSend()
end
function Postal:OnEnable()
self:RegisterEvent('UI_ERROR_MESSAGE')
self:RegisterEvent('MAIL_SEND_SUCCESS')
self:RegisterEvent('MAIL_CLOSED')
self:Hook('ContainerFrameItemButton_OnClick')
self:Hook('PickupContainerItem')
self:Hook('UseContainerItem')
self:Hook('ClickSendMailItemButton')
self:Hook('SendMailFrame_Update')
self:Hook('SendMailFrame_CanSend')
self:Hook('SetItemButtonDesaturated')
self:Hook('InboxFrame_OnClick')
self:Hook('InboxFrameItem_OnEnter')
self:Hook('InboxFrame_Update')
SendMailFrame:CreateTexture('PostalHorizontalBarLeft', 'BACKGROUND')
PostalHorizontalBarLeft:SetTexture([[Interface\ClassTrainerFrame\UI-ClassTrainer-HorizontalBar]])
PostalHorizontalBarLeft:SetWidth(256)
PostalHorizontalBarLeft:SetHeight(16)
PostalHorizontalBarLeft:SetTexCoord(0, 1, 0, 0.25)
SendMailFrame:CreateTexture('PostalHorizontalBarRight', 'BACKGROUND')
PostalHorizontalBarRight:SetTexture([[Interface\ClassTrainerFrame\UI-ClassTrainer-HorizontalBar]])
PostalHorizontalBarRight:SetWidth(75)
PostalHorizontalBarRight:SetHeight(16)
PostalHorizontalBarRight:SetTexCoord(0, 0.29296875, 0.25, 0.5)
PostalHorizontalBarRight:SetPoint('LEFT', PostalHorizontalBarLeft, 'RIGHT')
do
local background = ({SendMailPackageButton:GetRegions()})[1]
background:Hide()
local count = ({SendMailPackageButton:GetRegions()})[3]
count:Hide()
SendMailPackageButton:Disable()
SendMailPackageButton:SetScript('OnReceiveDrag', nil)
SendMailPackageButton:SetScript('OnDragStart', nil)
end
do
SendMailMoneyText:SetPoint('TOPLEFT', 0, -2)
SendMailMoney:ClearAllPoints()
SendMailMoney:SetPoint('TOPLEFT', SendMailMoneyText, 'BOTTOMLEFT', 5, -3)
SendMailSendMoneyButton:SetPoint('TOPLEFT', SendMailMoney, 'TOPRIGHT', 0, 12)
end
PostalMailButton:SetScript('OnClick', function()
PostalGlobalFrame.first = true
PostalGlobalFrame.to = SendMailNameEditBox:GetText()
PostalGlobalFrame.subject = PostalSubjectEditBox:GetText() ~= '' and PostalSubjectEditBox:GetText()
PostalGlobalFrame.body = SendMailBodyEditBox:GetText()
PostalGlobalFrame.money = MoneyInputFrame_GetCopper(SendMailMoney)
PostalGlobalFrame.cod = SendMailCODButton:GetChecked()
PostalGlobalFrame.queue = Postal:AttachmentList()
PostalGlobalFrame.total = getn(PostalGlobalFrame.queue)
PostalGlobalFrame:Show()
POSTAL_CANSENDNEXT = 1
Postal:ClearItems()
Postal:SendMailFrame_Update()
end)
-- hack to avoid automatic subject setting/button enabling
SendMailMailButton:Hide()
SendMailSubjectEditBox:Hide()
SendMailSubjectEditBox.SetText = function(self, text) PostalSubjectEditBox:SetText(text) end
SendMailNameEditBox:SetScript('OnTabPressed', function()
PostalSubjectEditBox:SetFocus()
end)
SendMailNameEditBox:SetScript('OnEnterPressed', function()
PostalSubjectEditBox:SetFocus()
end)
SendMailBodyEditBox:SetScript('OnTabPressed', function()
if IsShiftKeyDown() then
PostalSubjectEditBox:SetFocus()
else
SendMailMoneyGold:SetFocus()
end
end)
Postal:SendMailFrame_Update()
end
function Postal:MAIL_CLOSED()
PostalGlobalFrame:Hide()
Postal:Inbox_Abort()
Postal:ClearItems()
-- Hides the minimap unread mail button if there are no unread mail on closing the mailbox.
-- Does not scan past the first 50 items since only the first 50 are viewable.
for i=1,GetInboxNumItems() do
local wasRead = ({ GetInboxHeaderInfo(i) })[9]
if not wasRead then
return
end
end
MiniMapMailFrame:Hide()
-- There may be an UPDATE PENDING MAIL event after closing which would make the frame reappear, the following prevents that
local t = GetTime()
MiniMapMailFrame.Show = function()
if GetTime() - t > 2 then
MiniMapMailFrame.Show = Postal_MiniMapMailFrame_Show_Orig
MiniMapMailFrame:Show()
end
end
end
function Postal:MAIL_SEND_SUCCESS()
POSTAL_CANSENDNEXT = 1
end
function Postal:ContainerFrameItemButton_OnClick(btn, ignore)
local bag, slot = this:GetParent():GetID(), this:GetID()
if self:SelectedAttachment(bag, slot) or self:QueuedAttachment(bag, slot) then
return
end
self.hooks["ContainerFrameItemButton_OnClick"].orig(btn, ignore)
end
function Postal:PickupContainerItem(bag, slot)
if self:SelectedAttachment(bag, slot) or self:QueuedAttachment(bag, slot) then
return
end
if not CursorHasItem() then
PostalFrame.bag = bag
PostalFrame.slot = slot
end
self.hooks["PickupContainerItem"].orig(bag, slot)
end
function Postal:AttachItem(bag, slot)
for i = 1, ATTACHMENTS_MAX do
if not getglobal("PostalAttachment" .. i).slot then
if not self:ItemIsMailable(bag, slot) then
Postal:Print("Postal: Cannot attach item.", 1, 0.5, 0)
return
end
self.hooks["PickupContainerItem"].orig(bag, slot)
self:AttachmentButton_OnClick(getglobal("PostalAttachment" .. i))
return
end
end
end
function Postal:UseContainerItem(bag, slot)
if IsShiftKeyDown() or IsControlKeyDown() or IsAltKeyDown() then
return self.hooks["UseContainerItem"].orig(bag, slot)
end
if self:SelectedAttachment(bag, slot) or self:QueuedAttachment(bag, slot) then
return
end
if not CursorHasItem() then
PostalFrame.bag = bag
PostalFrame.slot = slot
end
if SendMailFrame:IsVisible() and not CursorHasItem() then
self:AttachItem(bag, slot)
return
elseif TradeFrame:IsVisible() and not CursorHasItem() then
for i = 1, 6 do
if not GetTradePlayerItemLink(i) then
self.hooks["PickupContainerItem"].orig(bag, slot)
ClickTradeButton(i)
return
end
end
end
self.hooks["UseContainerItem"].orig(bag, slot)
end
-- Handle the dragging of items
function Postal:AttachmentButton_OnClick(button)
button = button or this
if CursorHasItem() then
local bag, slot = PostalFrame.bag, PostalFrame.slot
if not bag or not slot then return end
if not self:ItemIsMailable(bag, slot) then
Postal:Print("Postal: Cannot attach item.", 1, 0.5, 0)
ClearCursor()
return
end
local oldBag, oldSlot = button.bag, button.slot
button.bag, button.slot = bag, slot
ClearCursor() -- triggers lock changed event
if oldBag and oldSlot then
self:PickupContainerItem(oldBag, oldSlot)
else
PostalFrame.bag, PostalFrame.slot = nil, nil
end
elseif button.bag and button.slot then
PostalFrame.bag, PostalFrame.slot = button.bag, button.slot
self.hooks["PickupContainerItem"].orig(button.bag, button.slot)
button.bag, button.slot = nil, nil
end
Postal:SendMailFrame_Update()
end
function Postal:ItemIsMailable(bag, slot)
-- Make sure tooltip is cleared
for i=1,29 do
getglobal("PostalTooltipTextLeft" .. i):SetText("")
end
PostalTooltip:SetBagItem(bag, slot)
for i=1,PostalTooltip:NumLines() do
local text = getglobal("PostalTooltipTextLeft" .. i):GetText()
if text == ITEM_SOULBOUND or text == ITEM_BIND_QUEST or text == ITEM_CONJURED or text == ITEM_BIND_ON_PICKUP then
return false
end
end
return true
end
function Postal:SelectedAttachment(bag, slot)
for i=1,ATTACHMENTS_MAX do
local btn = getglobal("PostalAttachment" .. i)
if btn.slot == slot and btn.bag == bag then
return true
end
end
end
function Postal:QueuedAttachment(bag, slot)
for _, attachment in ipairs(PostalGlobalFrame.queue or {}) do
if attachment.slot == slot and attachment.bag == bag then
return true
end
end
end
function Postal:GetNumMails()
local num = 0
for i=1,ATTACHMENTS_MAX do
local btn = getglobal("PostalAttachment" .. i)
if btn.slot and btn.bag then
num = num + 1
end
end
return num
end
function Postal:ClearItems()
local num = 0
for i=1,ATTACHMENTS_MAX do
local btn = getglobal("PostalAttachment" .. i)
btn.slot = nil
btn.bag = nil
end
PostalMailButton:Disable()
SendMailNameEditBox:SetText('')
SendMailNameEditBox:SetFocus()
PostalSubjectEditBox:SetText('')
SendMailBodyEditBox:SetText('')
MoneyInputFrame_ResetMoney(SendMailMoney)
SendMailRadioButton_OnClick(1)
end
function Postal:SendMailFrame_CanSend()
if strlen(SendMailNameEditBox:GetText()) > 0 and (SendMailSendMoneyButton:GetChecked() and MoneyInputFrame_GetCopper(SendMailMoney) or 0) + GetSendMailPrice() * self:GetNumMails() <= GetMoney() then
PostalMailButton:Enable()
else
PostalMailButton:Disable()
end
end
-- handle the weird built-in mail body textbox onclick
function Postal:ClickSendMailItemButton()
ClearCursor()
Postal.control.as_soon_as(function() return not ({GetContainerItemInfo(PostalFrame.bag or 0, PostalFrame.slot or 0)})[3] end, function()
if PostalFrame.bag and PostalFrame.slot then
self:AttachItem(PostalFrame.bag, PostalFrame.slot)
end
end)
end
function Postal:SendMail()
local item = tremove(this.queue, 1)
if item or this.first then
local subject = this.subject or '[No Subject]'
if this.total > 1 then
subject = subject..format(' (Part %d of %d)', this.total - getn(this.queue), this.total)
end
if item then
ClearCursor()
self.hooks["ClickSendMailItemButton"].orig()
ClearCursor()
self.hooks["PickupContainerItem"].orig(item.bag, item.slot)
self.hooks["ClickSendMailItemButton"].orig()
local name, _, count = GetSendMailItem()
if not name then
Postal:Print("Postal: An error occured in POSTAL. This might be related to lag, trying to send items with an item placed in the normal send mail window, or trying to send items that cannot be sent.", 1, 0, 0)
PostalGlobalFrame:Hide()
return
end
end
if this.first then
this.first = false
if this.money then
if this.cod then
SetSendMailCOD(this.money)
else
SetSendMailMoney(this.money)
end
end
end
SendMail(this.to, subject, this.body)
return
end
PostalGlobalFrame:Hide()
end
function Postal:AttachmentList()
local arr = {}
for i = 1, ATTACHMENTS_MAX do
local btn = getglobal("PostalAttachment" .. i)
if btn.slot and btn.bag then
tinsert(arr, { slot = btn.slot, bag = btn.bag })
end
end
return arr
end
function Postal:ProcessQueue(elapsed)
if not POSTAL_CANSENDNEXT then
return
end
POSTAL_CANSENDNEXT = nil
self:SendMail()
end
function Postal:SetItemButtonDesaturated(itemButton, locked)
local bag, slot = itemButton:GetParent():GetID(), itemButton:GetID()
if self:SelectedAttachment(bag, slot) or self:QueuedAttachment(bag, slot) then
return self.hooks["SetItemButtonDesaturated"].orig(itemButton, true)
end
return self.hooks["SetItemButtonDesaturated"].orig(itemButton, locked)
end
function Postal:InboxFrameItem_OnEnter()
local didSetTooltip
if this.index then
if GetInboxItem(this.index) then
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
GameTooltip:SetInboxItem(this.index)
didSetTooltip = 1
end
end
if not didSetTooltip then
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
end
if this.money then
GameTooltip:AddLine(ENCLOSED_MONEY, "", 1, 1, 1)
SetTooltipMoney(GameTooltip, this.money)
SetMoneyFrameColor("GameTooltipMoneyFrame", HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b)
elseif this.cod then
GameTooltip:AddLine(COD_AMOUNT, "", 1, 1, 1)
SetTooltipMoney(GameTooltip, this.cod)
if this.cod > GetMoney() then
SetMoneyFrameColor("GameTooltipMoneyFrame", RED_FONT_COLOR.r, RED_FONT_COLOR.g, RED_FONT_COLOR.b)
else
SetMoneyFrameColor("GameTooltipMoneyFrame", HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b)
end
end
if didSetTooltip and (this.money or this.cod) then
GameTooltip:SetHeight(GameTooltip:GetHeight()+getglobal("GameTooltipTextLeft" .. GameTooltip:NumLines()):GetHeight())
if GameTooltipMoneyFrame:IsVisible() then
GameTooltip:SetHeight(GameTooltip:GetHeight()+GameTooltipMoneyFrame:GetHeight())
end
end
GameTooltip:Show()
end
function Postal:UI_ERROR_MESSAGE()
if event == "UI_ERROR_MESSAGE" and (arg1 == ERR_INV_FULL or arg1 == ERR_ITEM_MAX_COUNT) then
if this.num then
if arg1 == ERR_INV_FULL then
Postal:Inbox_Abort()
Postal:Print("Postal: Inventory full. Aborting.", 1, 0, 0)
elseif arg1 == ERR_ITEM_MAX_COUNT then
Postal:Print("Postal: You already have the maximum amount of that item. Skipping.", 1, 0, 0)
if this.lastVal then
for key, va in this.id do
if va >= this.lastVal then
this.id[key] = va + 1
end
end
end
end
end
end
end
function Postal:Print(msg, r, g, b)
DEFAULT_CHAT_FRAME:AddMessage(msg, r, g, b)
end
function Postal_Inbox_SetSelected()
local id = this:GetID() + (InboxFrame.pageNum - 1) * 7
if not this:GetChecked() then
for k, v in Postal_SelectedItems do
if v == id then
tremove(Postal_SelectedItems, k)
break
end
end
else
tinsert(Postal_SelectedItems, id)
end
end
function Postal_Inbox_OpenSelected(open_all)
local selected = {}
if open_all then
for i = 1, GetInboxNumItems() do
tinsert(selected, i)
end
else
for _, i in Postal_SelectedItems do
tinsert(selected, i)
end
sort(selected)
end
PostalInboxFrame.opening = true
Postal:Inbox_DisableClicks()
Postal.open.start(selected, function()
PostalInboxFrame.opening = false
Postal:Inbox_DisableClicks()
end)
Postal_SelectedItems = {}
end
function Postal:InboxFrame_Update()
self.hooks["InboxFrame_Update"].orig()
for i = 1, 7 do
local index = (i + (InboxFrame.pageNum - 1) * 7)
if index > GetInboxNumItems() then
getglobal("PostalBoxItem" .. i .. "CB"):Hide()
else
getglobal("PostalBoxItem" .. i .. "CB"):Show()
getglobal("PostalBoxItem" .. i .. "CB"):SetChecked(nil)
for k, v in Postal_SelectedItems do
if v == index then
getglobal("PostalBoxItem" .. i .. "CB"):SetChecked(1)
break
end
end
end
end
Postal:Inbox_DisableClicks()
end
function Postal:Inbox_DisableClicks()
for i=1,7 do
getglobal('MailItem'..i..'ButtonIcon'):SetDesaturated(PostalInboxFrame.opening)
if PostalInboxFrame.opening then
getglobal('MailItem'..i..'Button'):SetChecked(nil)
end
end
end
function Postal:InboxFrame_OnClick(index)
if PostalInboxFrame.opening then
this:SetChecked(nil)
return
end
self.hooks['InboxFrame_OnClick'].orig(index)
end
function Postal:Inbox_Abort()
Postal.open.stop()
PostalInboxFrame.opening = false
Postal:Inbox_DisableClicks()
Postal_SelectedItems = {}
end