Initial commit as TurtleMail
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
root = true
|
||||
|
||||
[*.lua]
|
||||
max_line_length = 160
|
||||
space_inside_function_call_parentheses = true
|
||||
space_inside_function_param_list_parentheses = true
|
||||
space_inside_square_brackets = true
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json",
|
||||
"Lua.diagnostics.globals": [
|
||||
"arg1",
|
||||
"_",
|
||||
"this",
|
||||
"event"
|
||||
],
|
||||
"Lua.workspace.checkThirdParty": false,
|
||||
"Lua.workspace.ignoreDir": [],
|
||||
"workspace.library": [],
|
||||
"diagnostics.disable": [],
|
||||
"Lua.hint.enable": true
|
||||
}
|
||||
@@ -1,793 +0,0 @@
|
||||
Mail = CreateFrame('Frame', nil, MailFrame)
|
||||
local _G = getfenv(0)
|
||||
setfenv(1, setmetatable(Mail, {__index=_G}))
|
||||
|
||||
do
|
||||
local f = CreateFrame'Frame'
|
||||
f:SetScript('OnEvent', function() Mail[event]() end)
|
||||
for _, event in {'ADDON_LOADED', 'PLAYER_LOGIN', 'UI_ERROR_MESSAGE', 'CURSOR_UPDATE', 'BAG_UPDATE', 'MAIL_CLOSED', 'MAIL_SEND_SUCCESS', 'MAIL_INBOX_UPDATE'} do
|
||||
f:RegisterEvent(event)
|
||||
end
|
||||
end
|
||||
|
||||
_G.Mail_AutoCompleteNames = {}
|
||||
|
||||
local ATTACHMENTS_MAX = 21
|
||||
local ATTACHMENTS_PER_ROW_SEND = 7
|
||||
local ATTACHMENTS_MAX_ROWS_SEND = 3
|
||||
|
||||
function pack(...) return arg end
|
||||
|
||||
do
|
||||
local f = CreateFrame'Frame'
|
||||
local cursorItem
|
||||
function CURSOR_UPDATE()
|
||||
cursorItem = nil
|
||||
end
|
||||
function GetCursorItem()
|
||||
return cursorItem
|
||||
end
|
||||
function SetCursorItem(item)
|
||||
f:SetScript('OnUpdate', function()
|
||||
cursorItem = item
|
||||
f:SetScript('OnUpdate', nil)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function BAG_UPDATE()
|
||||
if MailFrame:IsVisible() then
|
||||
SendMailFrame_Update()
|
||||
end
|
||||
end
|
||||
|
||||
function MAIL_CLOSED()
|
||||
Inbox_Abort()
|
||||
SendMail_sending = false
|
||||
SendMail_Clear()
|
||||
end
|
||||
|
||||
do
|
||||
local f = CreateFrame'Frame'
|
||||
local function update()
|
||||
f:SetScript('OnUpdate', nil)
|
||||
SendMail_Send()
|
||||
end
|
||||
function MAIL_SEND_SUCCESS()
|
||||
if SendMail_state then
|
||||
addAutoCompleteName(SendMail_state.to)
|
||||
end
|
||||
if SendMail_sending then
|
||||
f:SetScript('OnUpdate', update)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function UI_ERROR_MESSAGE()
|
||||
if Inbox_opening then
|
||||
if arg1 == ERR_INV_FULL then
|
||||
Inbox_Abort()
|
||||
elseif arg1 == ERR_ITEM_MAX_COUNT then
|
||||
Inbox_skip = true
|
||||
end
|
||||
elseif SendMail_sending and (arg1 == ERR_MAIL_TO_SELF or arg1 == ERR_PLAYER_WRONG_FACTION or arg1 == ERR_MAIL_TARGET_NOT_FOUND or arg1 == ERR_MAIL_REACHED_CAP) then
|
||||
SendMail_sending = false
|
||||
SendMail_state = nil
|
||||
ClearCursor()
|
||||
orig.ClickSendMailItemButton()
|
||||
ClearCursor()
|
||||
end
|
||||
end
|
||||
|
||||
orig = {}
|
||||
do
|
||||
local hooks = {}
|
||||
hook = setmetatable({}, {__newindex=function(_, k, v) hooks[k] = v end})
|
||||
function PLAYER_LOGIN()
|
||||
for k, v in hooks do
|
||||
orig[k] = _G[k]
|
||||
_G[k] = v
|
||||
end
|
||||
local key = GetCVar'realmName' .. '|' .. UnitFactionGroup'player'
|
||||
Mail_AutoCompleteNames[key] = Mail_AutoCompleteNames[key] or {}
|
||||
for char, lastSeen in Mail_AutoCompleteNames[key] do
|
||||
if GetTime() - lastSeen > 60 * 60 * 24 * 30 then
|
||||
Mail_AutoCompleteNames[key][char] = nil
|
||||
end
|
||||
end
|
||||
function addAutoCompleteName(name)
|
||||
Mail_AutoCompleteNames[key][name] = GetTime()
|
||||
end
|
||||
addAutoCompleteName(UnitName'player')
|
||||
end
|
||||
end
|
||||
|
||||
function hook.GetInboxHeaderInfo(...)
|
||||
local sender, canReply = arg[3], arg[12]
|
||||
if sender and canReply then
|
||||
addAutoCompleteName(sender)
|
||||
end
|
||||
return orig.GetInboxHeaderInfo(unpack(arg))
|
||||
end
|
||||
|
||||
function ADDON_LOADED()
|
||||
if arg1 ~= 'Mail' then return end
|
||||
|
||||
UIPanelWindows.MailFrame.pushable = 1
|
||||
UIPanelWindows.FriendsFrame.pushable = 2
|
||||
|
||||
Inbox_Load()
|
||||
SendMail_Load()
|
||||
end
|
||||
|
||||
function hook.OpenMail_Reply(...)
|
||||
_G.Mail_To = nil
|
||||
return orig.OpenMail_Reply(unpack(arg))
|
||||
end
|
||||
|
||||
function hook.InboxFrame_Update()
|
||||
orig.InboxFrame_Update()
|
||||
for i = 1, 7 do
|
||||
-- hack for tooltip update
|
||||
_G['MailItem' .. i]:Hide()
|
||||
_G['MailItem' .. i]:Show()
|
||||
end
|
||||
Inbox_UpdateLock()
|
||||
end
|
||||
|
||||
function hook.InboxFrame_OnClick(i)
|
||||
if Inbox_opening or arg1 == 'RightButton' and ({GetInboxHeaderInfo(i)})[6] > 0 then
|
||||
this:SetChecked(nil)
|
||||
elseif arg1 == 'RightButton' then
|
||||
Inbox_Open(i)
|
||||
else
|
||||
return orig.InboxFrame_OnClick(i)
|
||||
end
|
||||
end
|
||||
|
||||
function hook.InboxFrameItem_OnEnter()
|
||||
orig.InboxFrameItem_OnEnter()
|
||||
if GetInboxItem(this.index) then
|
||||
GameTooltip:AddLine(ITEM_OPENABLE, '', 0, 1, 0)
|
||||
GameTooltip:Show()
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local x = 0
|
||||
CreateFrame('Frame', InboxFrame):SetScript('OnUpdate', function()
|
||||
if x > 0 then
|
||||
x = x - 1
|
||||
elseif not Inbox_opening then
|
||||
x = 100
|
||||
CheckInbox()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function Inbox_Load()
|
||||
local btn = CreateFrame('Button', nil, InboxFrame, 'UIPanelButtonTemplate')
|
||||
btn:SetPoint('BOTTOM', -10, 90)
|
||||
btn:SetText(OPENMAIL)
|
||||
btn:SetWidth(max(120, 30 + ({btn:GetRegions()})[1]:GetStringWidth()))
|
||||
btn:SetHeight(25)
|
||||
btn:SetScript('OnClick', Inbox_OpenAll)
|
||||
end
|
||||
|
||||
do
|
||||
local i, update
|
||||
local f = CreateFrame'Frame'
|
||||
f:Hide()
|
||||
f:SetScript('OnUpdate', function()
|
||||
if update then
|
||||
update = false
|
||||
local _, _, _, _, _, COD, _, _, _, _, _, _, isGM = GetInboxHeaderInfo(i)
|
||||
if i > GetInboxNumItems() then
|
||||
Inbox_Abort()
|
||||
elseif Inbox_Skip or COD > 0 or isGM then
|
||||
Inbox_Skip = false
|
||||
i = i + 1
|
||||
update = true
|
||||
else
|
||||
Inbox_Open(i)
|
||||
end
|
||||
end
|
||||
end)
|
||||
function MAIL_INBOX_UPDATE()
|
||||
if Inbox_opening then
|
||||
update = true
|
||||
end
|
||||
end
|
||||
function Inbox_OpenAll()
|
||||
Inbox_opening = true
|
||||
Inbox_UpdateLock()
|
||||
i = 1
|
||||
Inbox_skip = false
|
||||
update = true
|
||||
f:Show()
|
||||
end
|
||||
function Inbox_Abort()
|
||||
Inbox_opening = false
|
||||
Inbox_UpdateLock()
|
||||
f:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local TakeInboxMoney, TakeInboxItem, DeleteInboxItem = TakeInboxMoney, TakeInboxItem, DeleteInboxItem -- hack to prevent beancounter from deleting mail
|
||||
function Inbox_Open(i)
|
||||
GetInboxText(i)
|
||||
TakeInboxMoney(i)
|
||||
TakeInboxItem(i)
|
||||
DeleteInboxItem(i)
|
||||
end
|
||||
end
|
||||
|
||||
function Inbox_UpdateLock()
|
||||
for i = 1, 7 do
|
||||
_G['MailItem' .. i .. 'ButtonIcon']:SetDesaturated(Inbox_opening)
|
||||
if Inbox_opening then
|
||||
_G['MailItem' .. i .. 'Button']:SetChecked(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function hook.SendMailFrame_Update()
|
||||
local itemCount = 0
|
||||
local itemTitle
|
||||
local gap
|
||||
-- local last = 0 blizzlike
|
||||
local last = SendMail_NumAttachments()
|
||||
|
||||
for i = 1, ATTACHMENTS_MAX do
|
||||
local btn = _G['MailAttachment' .. i]
|
||||
|
||||
local texture, count
|
||||
if btn.item then
|
||||
texture, count = GetContainerItemInfo(unpack(btn.item))
|
||||
end
|
||||
if not texture then
|
||||
btn:SetNormalTexture(nil)
|
||||
_G[btn:GetName() .. 'Count']:Hide()
|
||||
btn.item = nil
|
||||
else
|
||||
btn:SetNormalTexture(texture)
|
||||
if count > 1 then
|
||||
_G[btn:GetName() .. 'Count']:Show()
|
||||
_G[btn:GetName() .. 'Count']:SetText(count)
|
||||
else
|
||||
_G[btn:GetName() .. 'Count']:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if SendMail_NumAttachments() > 0 then
|
||||
SendMailCODButton:Enable()
|
||||
SendMailCODButtonText:SetTextColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b)
|
||||
else
|
||||
SendMailSendMoneyButton:SetChecked(1)
|
||||
SendMailCODButton:SetChecked(nil)
|
||||
SendMailMoneyText:SetText(AMOUNT_TO_SEND)
|
||||
SendMailCODButton:Disable()
|
||||
SendMailCODButtonText:SetTextColor(GRAY_FONT_COLOR.r, GRAY_FONT_COLOR.g, GRAY_FONT_COLOR.b)
|
||||
end
|
||||
|
||||
MoneyFrame_Update('SendMailCostMoneyFrame', GetSendMailPrice() * max(1, SendMail_NumAttachments()))
|
||||
|
||||
-- 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 = MailAttachment1:GetWidth() + 2
|
||||
local icony = MailAttachment1: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
|
||||
|
||||
MailHorizontalBarLeft: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, .484375, 0, scrollHeight / 256)
|
||||
|
||||
StationeryBackgroundLeft:SetHeight(scrollHeight)
|
||||
StationeryBackgroundLeft:SetTexCoord(0, 1, 0, scrollHeight / 256)
|
||||
|
||||
|
||||
StationeryBackgroundRight:SetHeight(scrollHeight)
|
||||
StationeryBackgroundRight:SetTexCoord(0, 1, 0, scrollHeight / 256)
|
||||
|
||||
-- Set Items
|
||||
for i = 1, ATTACHMENTS_MAX do
|
||||
if cursory >= 0 then
|
||||
_G['MailAttachment' .. i]:Enable()
|
||||
_G['MailAttachment' .. i]:Show()
|
||||
_G['MailAttachment' .. 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
|
||||
_G['MailAttachment' .. i]:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
SendMailFrame_CanSend()
|
||||
end
|
||||
|
||||
function hook.ClickSendMailItemButton()
|
||||
SendMail_SetAttachment(GetCursorItem())
|
||||
end
|
||||
|
||||
function hook.GetContainerItemInfo(bag, slot)
|
||||
local ret = pack(orig.GetContainerItemInfo(bag, slot))
|
||||
ret[3] = ret[3] or SendMail_Attached(bag, slot) and 1 or nil
|
||||
return unpack(ret)
|
||||
end
|
||||
|
||||
function hook.PickupContainerItem(bag, slot)
|
||||
if SendMail_Attached(bag, slot) then return end
|
||||
if GetContainerItemInfo(bag, slot) then SetCursorItem{bag, slot} end
|
||||
return orig.PickupContainerItem(bag, slot)
|
||||
end
|
||||
|
||||
function hook.SplitContainerItem(bag, slot, amount)
|
||||
if SendMail_Attached(bag, slot) then return end
|
||||
return orig.SplitContainerItem(bag, slot, amount)
|
||||
end
|
||||
|
||||
function hook.UseContainerItem(bag, slot, onself)
|
||||
if SendMail_Attached(bag, slot) then return end
|
||||
if IsShiftKeyDown() or IsControlKeyDown() or IsAltKeyDown() then
|
||||
return orig.UseContainerItem(bag, slot, onself)
|
||||
elseif MailFrame:IsVisible() then
|
||||
MailFrameTab_OnClick(2)
|
||||
SendMail_SetAttachment{bag, slot}
|
||||
elseif TradeFrame:IsVisible() then
|
||||
for i = 1, 6 do
|
||||
if not GetTradePlayerItemLink(i) then
|
||||
orig.PickupContainerItem(bag, slot)
|
||||
ClickTradeButton(i)
|
||||
return
|
||||
end
|
||||
end
|
||||
else
|
||||
return orig.UseContainerItem(bag, slot, onself)
|
||||
end
|
||||
end
|
||||
|
||||
function MailMailButton_OnClick()
|
||||
MailAutoCompleteBox:Hide()
|
||||
|
||||
_G.Mail_To = SendMailNameEditBox:GetText()
|
||||
SendMailNameEditBox:HighlightText()
|
||||
|
||||
SendMail_state = {
|
||||
to = Mail_To,
|
||||
subject = MailSubjectEditBox:GetText(),
|
||||
body = SendMailBodyEditBox:GetText(),
|
||||
money = MoneyInputFrame_GetCopper(SendMailMoney),
|
||||
cod = SendMailCODButton:GetChecked(),
|
||||
attachments = SendMail_Attachments(),
|
||||
numMessages = max(1, SendMail_NumAttachments()),
|
||||
}
|
||||
|
||||
SendMail_Clear()
|
||||
SendMail_sending = true
|
||||
SendMail_Send()
|
||||
end
|
||||
|
||||
function SendMail_Load()
|
||||
SendMailFrame:CreateTexture('MailHorizontalBarLeft', 'BACKGROUND')
|
||||
MailHorizontalBarLeft:SetTexture([[Interface\ClassTrainerFrame\UI-ClassTrainer-HorizontalBar]])
|
||||
MailHorizontalBarLeft:SetWidth(256)
|
||||
MailHorizontalBarLeft:SetHeight(16)
|
||||
MailHorizontalBarLeft:SetTexCoord(0, 1, 0, .25)
|
||||
SendMailFrame:CreateTexture('MailHorizontalBarRight', 'BACKGROUND')
|
||||
MailHorizontalBarRight:SetTexture([[Interface\ClassTrainerFrame\UI-ClassTrainer-HorizontalBar]])
|
||||
MailHorizontalBarRight:SetWidth(75)
|
||||
MailHorizontalBarRight:SetHeight(16)
|
||||
MailHorizontalBarRight:SetTexCoord(0, .29296875, .25, .5)
|
||||
MailHorizontalBarRight:SetPoint('LEFT', MailHorizontalBarLeft, '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
|
||||
|
||||
SendMailMoneyText:SetPoint('TOPLEFT', 0, 0)
|
||||
SendMailMoney:ClearAllPoints()
|
||||
SendMailMoney:SetPoint('TOPLEFT', SendMailMoneyText, 'BOTTOMLEFT', 5, -5)
|
||||
SendMailMoneyGoldRight:SetPoint('RIGHT', 20, 0)
|
||||
do ({SendMailMoneyGold:GetRegions()})[9]:SetDrawLayer('BORDER') end
|
||||
SendMailMoneyGold:SetMaxLetters(7)
|
||||
SendMailMoneyGold:SetWidth(50)
|
||||
SendMailMoneySilverRight:SetPoint('RIGHT', 10, 0)
|
||||
do ({SendMailMoneySilver:GetRegions()})[9]:SetDrawLayer('BORDER') end
|
||||
SendMailMoneySilver:SetWidth(28)
|
||||
SendMailMoneySilver:SetPoint('LEFT', SendMailMoneyGold, 'RIGHT', 30, 0)
|
||||
SendMailMoneyCopperRight:SetPoint('RIGHT', 10, 0)
|
||||
do ({SendMailMoneyCopper:GetRegions()})[9]:SetDrawLayer('BORDER') end
|
||||
SendMailMoneyCopper:SetWidth(28)
|
||||
SendMailMoneyCopper:SetPoint('LEFT', SendMailMoneySilver, 'RIGHT', 20, 0)
|
||||
SendMailSendMoneyButton:SetPoint('TOPLEFT', SendMailMoney, 'TOPRIGHT', 0, 12)
|
||||
|
||||
-- hack to avoid automatic subject setting and button disabling from weird blizzard code
|
||||
MailMailButton = SendMailMailButton
|
||||
_G.SendMailMailButton = setmetatable({}, {__index = function() return function() end end})
|
||||
_G.SendMailMailButton_OnClick = MailMailButton_OnClick
|
||||
MailSubjectEditBox = SendMailSubjectEditBox
|
||||
_G.SendMailSubjectEditBox = setmetatable({}, {
|
||||
__index = function(_, key)
|
||||
return function(_, ...)
|
||||
return MailSubjectEditBox[key](MailSubjectEditBox, unpack(arg))
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
SendMailNameEditBox._SetText = SendMailNameEditBox.SetText
|
||||
function SendMailNameEditBox:SetText(...)
|
||||
if not Mail_To then
|
||||
return self:_SetText(unpack(arg))
|
||||
end
|
||||
end
|
||||
SendMailNameEditBox:SetScript('OnShow', function()
|
||||
if Mail_To then
|
||||
this:_SetText(Mail_To)
|
||||
end
|
||||
end)
|
||||
SendMailNameEditBox:SetScript('OnChar', function()
|
||||
_G.Mail_To = nil
|
||||
GetSuggestions()
|
||||
end)
|
||||
SendMailNameEditBox:SetScript('OnTabPressed', function()
|
||||
if MailAutoCompleteBox:IsVisible() then
|
||||
if IsShiftKeyDown() then
|
||||
PreviousMatch()
|
||||
else
|
||||
NextMatch()
|
||||
end
|
||||
else
|
||||
MailSubjectEditBox:SetFocus()
|
||||
end
|
||||
end)
|
||||
SendMailNameEditBox:SetScript('OnEnterPressed', function()
|
||||
if MailAutoCompleteBox:IsVisible() then
|
||||
MailAutoCompleteBox:Hide()
|
||||
this:HighlightText(0, 0)
|
||||
else
|
||||
MailSubjectEditBox:SetFocus()
|
||||
end
|
||||
end)
|
||||
SendMailNameEditBox:SetScript('OnEscapePressed', function()
|
||||
if MailAutoCompleteBox:IsVisible() then
|
||||
MailAutoCompleteBox:Hide()
|
||||
else
|
||||
this:ClearFocus()
|
||||
end
|
||||
end)
|
||||
function SendMailNameEditBox.focusLoss()
|
||||
MailAutoCompleteBox:Hide()
|
||||
end
|
||||
do
|
||||
local orig = SendMailNameEditBox:GetScript'OnTextChanged'
|
||||
SendMailNameEditBox:SetScript('OnTextChanged', function()
|
||||
local text = this:GetText()
|
||||
local formatted = gsub(strlower(text), '^%l', strupper)
|
||||
if text ~= formatted then
|
||||
this:SetText(formatted)
|
||||
end
|
||||
return orig()
|
||||
end)
|
||||
end
|
||||
|
||||
for _, editBox in {SendMailNameEditBox, SendMailSubjectEditBox} do
|
||||
editBox:SetScript('OnEditFocusGained', function()
|
||||
this:HighlightText()
|
||||
end)
|
||||
editBox:SetScript('OnEditFocusLost', function()
|
||||
(this.focusLoss or function() end)()
|
||||
this:HighlightText(0, 0)
|
||||
end)
|
||||
do
|
||||
local lastClick
|
||||
editBox:SetScript('OnMouseDown', function()
|
||||
local x, y = GetCursorPosition()
|
||||
if lastClick and GetTime() - lastClick.t < .5 and x == lastClick.x and y == lastClick.y then
|
||||
this:SetScript('OnUpdate', function()
|
||||
this:HighlightText()
|
||||
this:SetScript('OnUpdate', nil)
|
||||
end)
|
||||
end
|
||||
lastClick = {t=GetTime(), x=x, y=y}
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function hook.SendMailFrame_CanSend()
|
||||
if not SendMail_sending and strlen(SendMailNameEditBox:GetText()) > 0 and (SendMailSendMoneyButton:GetChecked() and MoneyInputFrame_GetCopper(SendMailMoney) or 0) + GetSendMailPrice() * max(1, SendMail_NumAttachments()) <= GetMoney() then
|
||||
MailMailButton:Enable()
|
||||
else
|
||||
MailMailButton:Disable()
|
||||
end
|
||||
end
|
||||
|
||||
function SendMail_Attached(bag, slot)
|
||||
if not MailFrame:IsVisible() then return false end
|
||||
for i = 1, ATTACHMENTS_MAX do
|
||||
local btn = _G['MailAttachment' .. i]
|
||||
if btn.item and btn.item[1] == bag and btn.item[2] == slot then
|
||||
return true
|
||||
end
|
||||
end
|
||||
if SendMail_state then
|
||||
for _, attachment in SendMail_state.attachments do
|
||||
if attachment[1] == bag and attachment[2] == slot then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function AttachmentButton_OnClick()
|
||||
local attachedItem = this.item
|
||||
local cursorItem = GetCursorItem()
|
||||
if SendMail_SetAttachment(cursorItem, this) then
|
||||
if attachedItem then
|
||||
if arg1 == 'LeftButton' then SetCursorItem(attachedItem) end
|
||||
orig.PickupContainerItem(unpack(attachedItem))
|
||||
if arg1 ~= 'LeftButton' then ClearCursor() end -- for the lock changed event
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- requires an item lock changed event for a proper update
|
||||
function SendMail_SetAttachment(item, slot)
|
||||
if item and not SendMail_PickupMailable(item) then
|
||||
ClearCursor()
|
||||
return
|
||||
elseif not slot then
|
||||
for i = 1, ATTACHMENTS_MAX do
|
||||
if not _G['MailAttachment' .. i].item then
|
||||
slot = _G['MailAttachment' .. i]
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if slot then
|
||||
if not (item or slot.item) then return true end
|
||||
slot.item = item
|
||||
ClearCursor()
|
||||
SendMailFrame_Update()
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function SendMail_PickupMailable(item)
|
||||
ClearCursor()
|
||||
orig.ClickSendMailItemButton()
|
||||
ClearCursor()
|
||||
orig.PickupContainerItem(unpack(item))
|
||||
orig.ClickSendMailItemButton()
|
||||
local mailable = GetSendMailItem() and true or false
|
||||
orig.ClickSendMailItemButton()
|
||||
return mailable
|
||||
end
|
||||
|
||||
function SendMail_NumAttachments()
|
||||
local x = 0
|
||||
for i = 1, ATTACHMENTS_MAX do
|
||||
if _G['MailAttachment' .. i].item then
|
||||
x = x + 1
|
||||
end
|
||||
end
|
||||
return x
|
||||
end
|
||||
|
||||
function SendMail_Attachments()
|
||||
local t = {}
|
||||
for i = 1, ATTACHMENTS_MAX do
|
||||
local btn = _G['MailAttachment' .. i]
|
||||
if btn.item then
|
||||
tinsert(t, btn.item)
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
function SendMail_Clear()
|
||||
local anyItem
|
||||
for i = 1, ATTACHMENTS_MAX do
|
||||
anyItem = anyItem or _G['MailAttachment' .. i].item
|
||||
_G['MailAttachment' .. i].item = nil
|
||||
end
|
||||
if anyItem then
|
||||
ClearCursor()
|
||||
PickupContainerItem(unpack(anyItem))
|
||||
ClearCursor()
|
||||
end
|
||||
MailMailButton:Disable()
|
||||
SendMailNameEditBox:SetText''
|
||||
SendMailNameEditBox:SetFocus()
|
||||
MailSubjectEditBox:SetText''
|
||||
SendMailBodyEditBox:SetText''
|
||||
MoneyInputFrame_ResetMoney(SendMailMoney)
|
||||
SendMailRadioButton_OnClick(1)
|
||||
|
||||
SendMailFrame_Update()
|
||||
end
|
||||
|
||||
function SendMail_Send()
|
||||
local item = tremove(SendMail_state.attachments, 1)
|
||||
if item then
|
||||
ClearCursor()
|
||||
orig.ClickSendMailItemButton()
|
||||
ClearCursor()
|
||||
orig.PickupContainerItem(unpack(item))
|
||||
orig.ClickSendMailItemButton()
|
||||
|
||||
if not GetSendMailItem() then
|
||||
DEFAULT_CHAT_FRAME:AddMessage('Mail: ' .. ERROR_CAPS, 1, 0, 0)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local amount = SendMail_state.money
|
||||
if amount > 0 then
|
||||
SendMail_state.money = 0
|
||||
if SendMail_state.cod then
|
||||
SetSendMailCOD(amount)
|
||||
else
|
||||
SetSendMailMoney(amount)
|
||||
end
|
||||
end
|
||||
|
||||
local subject = SendMail_state.subject
|
||||
if subject == '' then
|
||||
if item then
|
||||
local itemName, itemTexture, stackCount, quality = GetSendMailItem()
|
||||
subject = itemName .. (stackCount > 1 and ' (' .. stackCount .. ')' or '')
|
||||
else
|
||||
subject = '<' .. NO_ATTACHMENTS .. '>'
|
||||
end
|
||||
elseif SendMail_state.numMessages > 1 then
|
||||
subject = subject .. format(' [%d/%d]', SendMail_state.numMessages - getn(SendMail_state.attachments), SendMail_state.numMessages)
|
||||
end
|
||||
|
||||
SendMail(SendMail_state.to, subject, SendMail_state.body)
|
||||
|
||||
if getn(SendMail_state.attachments) == 0 then
|
||||
SendMail_sending = false
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local inputLength
|
||||
local matches = {}
|
||||
local index
|
||||
|
||||
local function complete()
|
||||
SendMailNameEditBox:SetText(matches[index])
|
||||
SendMailNameEditBox:HighlightText(inputLength, -1)
|
||||
for i = 1, MAIL_AUTOCOMPLETE_MAX_BUTTONS do
|
||||
local button = _G['MailAutoCompleteButton' .. i]
|
||||
if i == index then
|
||||
button:LockHighlight()
|
||||
else
|
||||
button:UnlockHighlight()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PreviousMatch()
|
||||
if index then
|
||||
index = index > 1 and index - 1 or getn(matches)
|
||||
complete()
|
||||
end
|
||||
end
|
||||
|
||||
function NextMatch()
|
||||
if index then
|
||||
index = mod(index, getn(matches)) + 1
|
||||
complete()
|
||||
end
|
||||
end
|
||||
|
||||
function SelectMatch(i)
|
||||
index = i
|
||||
complete()
|
||||
MailAutoCompleteBox:Hide()
|
||||
SendMailNameEditBox:HighlightText(0, 0)
|
||||
end
|
||||
|
||||
function GetSuggestions()
|
||||
local input = SendMailNameEditBox:GetText()
|
||||
inputLength = strlen(input)
|
||||
|
||||
table.setn(matches, 0)
|
||||
index = nil
|
||||
|
||||
local autoCompleteNames = {}
|
||||
for name, time in Mail_AutoCompleteNames[GetCVar'realmName' .. '|' .. UnitFactionGroup'player'] do
|
||||
tinsert(autoCompleteNames, {name=name, time=time})
|
||||
end
|
||||
sort(autoCompleteNames, function(a, b) return b.time < a.time end)
|
||||
|
||||
local ignore = {[UnitName'player']=true}
|
||||
local function process(name)
|
||||
if name then
|
||||
if not ignore[name] and strfind(strupper(name), strupper(input), nil, true) == 1 then
|
||||
tinsert(matches, name)
|
||||
end
|
||||
ignore[name] = true
|
||||
end
|
||||
end
|
||||
for _, t in autoCompleteNames do
|
||||
process(t.name)
|
||||
end
|
||||
for i = 1, GetNumFriends() do
|
||||
process(GetFriendInfo(i))
|
||||
end
|
||||
for i = 1, GetNumGuildMembers(true) do
|
||||
process(GetGuildRosterInfo(i))
|
||||
end
|
||||
|
||||
table.setn(matches, min(getn(matches), MAIL_AUTOCOMPLETE_MAX_BUTTONS))
|
||||
if getn(matches) > 0 and (getn(matches) > 1 or input ~= matches[1]) then
|
||||
for i = 1, MAIL_AUTOCOMPLETE_MAX_BUTTONS do
|
||||
local button = _G['MailAutoCompleteButton' .. i]
|
||||
if i <= getn(matches) then
|
||||
button:SetText(matches[i])
|
||||
button:GetFontString():SetPoint('LEFT', button, 'LEFT', 15, 0)
|
||||
button:Show()
|
||||
else
|
||||
button:Hide()
|
||||
end
|
||||
end
|
||||
MailAutoCompleteBox:SetHeight(getn(matches) * MailAutoCompleteButton1:GetHeight() + 35)
|
||||
MailAutoCompleteBox:SetWidth(120)
|
||||
MailAutoCompleteBox:Show()
|
||||
index = 1
|
||||
complete()
|
||||
else
|
||||
MailAutoCompleteBox:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,7 +0,0 @@
|
||||
## Interface: 11200
|
||||
## Title: Mail
|
||||
## Notes: Mailbox enhancement
|
||||
## Author: shirsig
|
||||
## SavedVariablesPerCharacter: Mail_To
|
||||
## SavedVariables: Mail_AutoCompleteNames
|
||||
Mail.xml
|
||||
@@ -1,19 +1,18 @@
|
||||
# Mail - WoW 1.12 addOn
|
||||
# TurtleMail - WoW 1.12 addOn
|
||||
|
||||
An extension to the Blizzard mail interface which
|
||||
- **Automatically opens mail, very rapidly**
|
||||
- **Mails multiple items at once, very rapidly**
|
||||
- **Autocompletes recipient names**
|
||||
- **Shows collected gold from opened mails**
|
||||
- **Apply COD to 1st or all mails**
|
||||
|
||||
**\<Right Click>** on inbox items to loot the gold, loot the item and destroy the letter, in that order, if any.<br/>
|
||||
**\<Right Click>** or **\<Left Drag>** to add inventory items to the attachments.<br/>
|
||||
**\<Right Click>** to add inventory items to the trade frame.
|
||||
|
||||
Note that due to limitations of the 1.12 API, behind the scenes, the items must be sent in separate mails.<br/>
|
||||
As a result of this **COD will only apply to the first item** if multiple items are added.
|
||||
Note that COD is always ignored when opening, both automatically as well as by **\<Right Click>**.
|
||||
|
||||
Also note that COD is always ignored when opening, both automatically as well as by **\<Right Click>**.
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
+998
@@ -0,0 +1,998 @@
|
||||
Mail = Mail or {}
|
||||
local m = Mail
|
||||
|
||||
local ATTACHMENTS_MAX = 21
|
||||
local ATTACHMENTS_PER_ROW_SEND = 7
|
||||
local ATTACHMENTS_MAX_ROWS_SEND = 3
|
||||
|
||||
local api = getfenv()
|
||||
local getn = table.getn ---@diagnostic disable-line: deprecated
|
||||
local money_received = 0
|
||||
local orig = {}
|
||||
local L = {}
|
||||
|
||||
do
|
||||
local f = api.CreateFrame( "Frame" )
|
||||
f:SetScript( "OnEvent", function() Mail[ event ]() end )
|
||||
|
||||
for _, event in { "ADDON_LOADED", "PLAYER_LOGIN", "UI_ERROR_MESSAGE", "CURSOR_UPDATE", "BAG_UPDATE", "MAIL_SHOW", "MAIL_CLOSED", "MAIL_SEND_SUCCESS", "MAIL_INBOX_UPDATE" } do
|
||||
f:RegisterEvent( event )
|
||||
end
|
||||
end
|
||||
|
||||
api.TurtleMail_AutoCompleteNames = {}
|
||||
|
||||
local function pack( ... ) return arg end
|
||||
|
||||
do
|
||||
local f = api.CreateFrame( "Frame" )
|
||||
local cursorItem
|
||||
function m.CURSOR_UPDATE()
|
||||
cursorItem = nil
|
||||
end
|
||||
|
||||
function GetCursorItem()
|
||||
return cursorItem
|
||||
end
|
||||
|
||||
function SetCursorItem( item )
|
||||
f:SetScript( "OnUpdate", function()
|
||||
cursorItem = item
|
||||
f:SetScript( "OnUpdate", nil )
|
||||
end )
|
||||
end
|
||||
end
|
||||
|
||||
function m.BAG_UPDATE()
|
||||
if api.MailFrame:IsVisible() then
|
||||
api.SendMailFrame_Update()
|
||||
end
|
||||
end
|
||||
|
||||
function m.MAIL_SHOW()
|
||||
if api.TurtleMail_Point then
|
||||
api.MailFrame:SetPoint( api.TurtleMail_Point.point, api.TurtleMail_Point.x, api.TurtleMail_Point.y )
|
||||
end
|
||||
end
|
||||
|
||||
function m.MAIL_CLOSED()
|
||||
Inbox_Abort()
|
||||
SendMail_sending = false
|
||||
SendMail_Clear()
|
||||
end
|
||||
|
||||
function m.UI_ERROR_MESSAGE()
|
||||
if Inbox_opening then
|
||||
if arg1 == api.ERR_INV_FULL then
|
||||
Inbox_Abort()
|
||||
elseif arg1 == api.ERR_ITEM_MAX_COUNT then
|
||||
Inbox_skip = true
|
||||
end
|
||||
elseif SendMail_sending and (arg1 == api.ERR_MAIL_TO_SELF or arg1 == api.ERR_PLAYER_WRONG_FACTION or arg1 == api.ERR_MAIL_TARGET_NOT_FOUND or arg1 == api.ERR_MAIL_REACHED_CAP) then
|
||||
SendMail_sending = false
|
||||
SendMail_state = nil
|
||||
api.ClearCursor()
|
||||
orig.ClickSendMailItemButton()
|
||||
api.ClearCursor()
|
||||
end
|
||||
end
|
||||
|
||||
function m.ADDON_LOADED()
|
||||
if arg1 ~= "TurtleMail" then return end
|
||||
|
||||
local version = api.GetAddOnMetadata( "TurtleMail", "Version" )
|
||||
api.DEFAULT_CHAT_FRAME:AddMessage( string.format( "|cffabd473TurtleMail|r: Loaded(|cffeda55fv%s|r).", version ) )
|
||||
|
||||
api.UIPanelWindows.MailFrame.pushable = 1
|
||||
api.UIPanelWindows.FriendsFrame.pushable = 2
|
||||
|
||||
Inbox_Load()
|
||||
SendMail_Load()
|
||||
end
|
||||
|
||||
do
|
||||
local f = api.CreateFrame( "Frame" )
|
||||
local function update()
|
||||
f:SetScript( "OnUpdate", nil )
|
||||
SendMail_Send()
|
||||
end
|
||||
function m.MAIL_SEND_SUCCESS()
|
||||
if SendMail_state then
|
||||
m.addAutoCompleteName( SendMail_state.to )
|
||||
end
|
||||
if SendMail_sending then
|
||||
f:SetScript( "OnUpdate", update )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function m.addAutoCompleteName( name )
|
||||
local key = api.GetCVar "realmName" .. "|" .. api.UnitFactionGroup "player"
|
||||
api.TurtleMail_AutoCompleteNames[ key ][ name ] = api.GetTime()
|
||||
end
|
||||
|
||||
do
|
||||
local x = 0
|
||||
api.CreateFrame( "Frame", api.InboxFrame ):SetScript( "OnUpdate", function()
|
||||
if x > 0 then
|
||||
x = x - 1
|
||||
elseif not Inbox_opening then
|
||||
x = 100
|
||||
api.CheckInbox()
|
||||
end
|
||||
end )
|
||||
end
|
||||
|
||||
function Inbox_Load()
|
||||
local btn = api.CreateFrame( "Button", nil, api.InboxFrame, "UIPanelButtonTemplate" )
|
||||
btn:SetPoint( "BOTTOM", -10, 90 )
|
||||
btn:SetText( api.OPENMAIL )
|
||||
btn:SetWidth( math.max( 120, 30 + ({ btn:GetRegions() })[ 1 ]:GetStringWidth() ) )
|
||||
btn:SetHeight( 25 )
|
||||
btn:SetScript( "OnClick", Inbox_OpenAll )
|
||||
|
||||
api.MailFrame:EnableMouse( true )
|
||||
api.MailFrame:SetMovable( true )
|
||||
api.MailFrame:SetScript( "OnDragStop", m.on_drag_stop )
|
||||
end
|
||||
|
||||
do
|
||||
local i, update
|
||||
local f = api.CreateFrame( "Frame" )
|
||||
f:Hide()
|
||||
f:SetScript( "OnUpdate", function()
|
||||
if update then
|
||||
update = false
|
||||
local _, _, _, _, _, COD, _, _, _, _, _, _, isGM = api.GetInboxHeaderInfo( i )
|
||||
if i > api.GetInboxNumItems() then
|
||||
if money_received > 0 then
|
||||
api.DEFAULT_CHAT_FRAME:AddMessage( string.format( "|cffabd473TurtleMail|r: %s%s.", m.format_money( money_received ), L[ "collected" ] ) )
|
||||
end
|
||||
Inbox_Abort()
|
||||
elseif Inbox_Skip or COD > 0 or isGM then
|
||||
Inbox_Skip = false
|
||||
i = i + 1
|
||||
update = true
|
||||
else
|
||||
Inbox_Open( i )
|
||||
end
|
||||
end
|
||||
end )
|
||||
|
||||
function m.MAIL_INBOX_UPDATE()
|
||||
if Inbox_opening then
|
||||
update = true
|
||||
end
|
||||
end
|
||||
|
||||
function Inbox_OpenAll()
|
||||
Inbox_opening = true
|
||||
Inbox_UpdateLock()
|
||||
i = 1
|
||||
Inbox_skip = false
|
||||
update = true
|
||||
f:Show()
|
||||
end
|
||||
|
||||
function Inbox_Abort()
|
||||
Inbox_opening = false
|
||||
Inbox_UpdateLock()
|
||||
f:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function m.set_cod_text()
|
||||
local text = string.sub( api.COD_AMOUNT, 1, string.len( api.COD_AMOUNT ) - 1 )
|
||||
|
||||
---@diagnostic disable-next-line: undefined-global
|
||||
if not pfUI or not pfUI.version then
|
||||
text = string.match( text, "^(.-)%s+%S+$" )
|
||||
end
|
||||
|
||||
if api.SendMailCODAllButton:GetChecked() then
|
||||
api.SendMailMoneyText:SetText( text .. " " .. L[ "each mail" ] .. ":" )
|
||||
else
|
||||
api.SendMailMoneyText:SetText( text .. " " .. L[ "1st mail" ] .. ":" )
|
||||
end
|
||||
end
|
||||
|
||||
---@param copper number
|
||||
function m.format_money( copper )
|
||||
local gold = math.floor( copper / 10000 )
|
||||
local silver = math.floor( (copper - gold * 10000) / 100 )
|
||||
local copper_remain = copper - (gold * 10000) - (silver * 100)
|
||||
|
||||
local result = ""
|
||||
if gold > 0 then
|
||||
result = result .. string.format( "|cffffffff%d|cffffd700g|r ", gold )
|
||||
end
|
||||
if silver > 0 then
|
||||
result = result .. string.format( "|cffffffff%d|cffc7c7cfs|r ", silver )
|
||||
end
|
||||
if copper_remain > 0 or result == "" then
|
||||
result = result .. string.format( "|cffffffff%d|cffeda55fc|r ", copper_remain )
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
---@param money number
|
||||
function m.update_money( money )
|
||||
money_received = money_received + money
|
||||
api.MoneyReceived:SetText( L[ "Money received" ] .. ": " .. m.format_money( money_received ) )
|
||||
|
||||
if money_received > 0 then
|
||||
api.MoneyReceived:Show()
|
||||
else
|
||||
api.MoneyReceived:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function m.on_drag_stop()
|
||||
local f = api.MailFrame
|
||||
if not f then return end
|
||||
f:StopMovingOrSizing()
|
||||
|
||||
local screen_width = api.GetScreenWidth()
|
||||
local screen_height = api.GetScreenHeight()
|
||||
local point, _, _, x, y = api.MailFrame:GetPoint()
|
||||
local nx, ny = x, y
|
||||
|
||||
if f:GetLeft() < 0 then nx = -10 end
|
||||
if f:GetRight() > screen_width + 28 then nx = screen_width + 28 - f:GetWidth() end
|
||||
if f:GetTop() > screen_height + 10 then ny = 10 end
|
||||
if f:GetBottom() < -40 then ny = -screen_height + f:GetHeight() - 40 end
|
||||
|
||||
if (nx ~= x or ny ~= y) then
|
||||
api.MailFrame:SetPoint( point, nx, ny )
|
||||
end
|
||||
|
||||
api.TurtleMail_Point = { point = point, x = nx, y = ny }
|
||||
end
|
||||
|
||||
do
|
||||
-- hack to prevent beancounter from deleting mail
|
||||
local TakeInboxMoney, TakeInboxItem, DeleteInboxItem = api.TakeInboxMoney, api.TakeInboxItem, api.DeleteInboxItem
|
||||
function Inbox_Open( i )
|
||||
local _, _, _, _, money, _, _, _, read, _, _, _, _ = api.GetInboxHeaderInfo( i )
|
||||
if money and read then
|
||||
m.update_money( money )
|
||||
end
|
||||
api.GetInboxText( i )
|
||||
|
||||
TakeInboxMoney( i )
|
||||
TakeInboxItem( i )
|
||||
DeleteInboxItem( i )
|
||||
end
|
||||
end
|
||||
|
||||
function Inbox_UpdateLock()
|
||||
for i = 1, 7 do
|
||||
api[ "MailItem" .. i .. "ButtonIcon" ]:SetDesaturated( Inbox_opening )
|
||||
if Inbox_opening then
|
||||
api[ "MailItem" .. i .. "Button" ]:SetChecked( nil )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Setup hooks
|
||||
do
|
||||
local hooks = {}
|
||||
m.hook = setmetatable( {}, { __newindex = function( _, k, v ) hooks[ k ] = v end } )
|
||||
function m.PLAYER_LOGIN()
|
||||
for k, v in hooks do
|
||||
orig[ k ] = api[ k ]
|
||||
api[ k ] = v
|
||||
end
|
||||
local key = api.GetCVar "realmName" .. "|" .. api.UnitFactionGroup "player"
|
||||
api.TurtleMail_AutoCompleteNames[ key ] = api.TurtleMail_AutoCompleteNames[ key ] or {}
|
||||
for char, lastSeen in api.TurtleMail_AutoCompleteNames[ key ] do
|
||||
if api.GetTime() - lastSeen > 60 * 60 * 24 * 30 then
|
||||
api.TurtleMail_AutoCompleteNames[ key ][ char ] = nil
|
||||
end
|
||||
end
|
||||
|
||||
m.addAutoCompleteName( api.UnitName "player" )
|
||||
end
|
||||
end
|
||||
|
||||
function m.hook.GetInboxHeaderInfo( ... )
|
||||
local sender, canReply = arg[ 3 ], arg[ 12 ]
|
||||
if sender and canReply then
|
||||
m.addAutoCompleteName( sender )
|
||||
end
|
||||
return orig.GetInboxHeaderInfo( unpack( arg ) )
|
||||
end
|
||||
|
||||
function m.hook.OpenMail_Reply( ... )
|
||||
api.TurtleMail_To = nil
|
||||
return orig.OpenMail_Reply( unpack( arg ) )
|
||||
end
|
||||
|
||||
function m.hook.InboxFrame_Update()
|
||||
orig.InboxFrame_Update()
|
||||
for i = 1, 7 do
|
||||
-- hack for tooltip update
|
||||
api[ "MailItem" .. i ]:Hide()
|
||||
api[ "MailItem" .. i ]:Show()
|
||||
end
|
||||
|
||||
do
|
||||
local currentPage = api.InboxFrame.pageNum
|
||||
local totalPages = math.ceil( api.GetInboxNumItems() / api.INBOXITEMS_TO_DISPLAY )
|
||||
local text = totalPages > 0 and (currentPage .. "/" .. totalPages) or ("Empty")
|
||||
api.InboxTitleText:SetText( "Inbox [" .. text .. "]" )
|
||||
end
|
||||
|
||||
Inbox_UpdateLock()
|
||||
end
|
||||
|
||||
function m.hook.InboxFrame_OnClick( i )
|
||||
if Inbox_opening or arg1 == "RightButton" and ({ api.GetInboxHeaderInfo( i ) })[ 6 ] > 0 then
|
||||
this:SetChecked( nil )
|
||||
elseif arg1 == "RightButton" then
|
||||
Inbox_Open( i )
|
||||
else
|
||||
return orig.InboxFrame_OnClick( i )
|
||||
end
|
||||
end
|
||||
|
||||
function m.hook.InboxFrameItem_OnEnter()
|
||||
orig.InboxFrameItem_OnEnter()
|
||||
if api.GetInboxItem( this.index ) then
|
||||
api.GameTooltip:AddLine( api.ITEM_OPENABLE, "", 0, 1, 0 )
|
||||
api.GameTooltip:Show()
|
||||
end
|
||||
end
|
||||
|
||||
function m.hook.SendMailFrame_Update()
|
||||
local gap
|
||||
-- local last = 0 blizzlike
|
||||
local last = SendMail_NumAttachments()
|
||||
|
||||
for i = 1, ATTACHMENTS_MAX do
|
||||
local btn = api[ "MailAttachment" .. i ]
|
||||
|
||||
local texture, count
|
||||
if btn.item then
|
||||
texture, count = api.GetContainerItemInfo( unpack( btn.item ) )
|
||||
end
|
||||
if not texture then
|
||||
btn:SetNormalTexture( nil )
|
||||
api[ btn:GetName() .. "Count" ]:Hide()
|
||||
btn.item = nil
|
||||
else
|
||||
btn:SetNormalTexture( texture )
|
||||
if count > 1 then
|
||||
api[ btn:GetName() .. "Count" ]:Show()
|
||||
api[ btn:GetName() .. "Count" ]:SetText( count )
|
||||
else
|
||||
api[ btn:GetName() .. "Count" ]:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if SendMail_NumAttachments() > 0 then
|
||||
api.SendMailCODButton:Enable()
|
||||
api.SendMailCODButtonText:SetTextColor( api.NORMAL_FONT_COLOR.r, api.NORMAL_FONT_COLOR.g, api.NORMAL_FONT_COLOR.b )
|
||||
if SendMail_NumAttachments() > 1 and api.SendMailCODButton:GetChecked() then
|
||||
api.SendMailCODAllButton:Enable()
|
||||
api.SendMailCODAllButtonText:SetTextColor( api.NORMAL_FONT_COLOR.r, api.NORMAL_FONT_COLOR.g, api.NORMAL_FONT_COLOR.b )
|
||||
m.set_cod_text()
|
||||
else
|
||||
api.SendMailCODAllButton:Disable()
|
||||
api.SendMailCODAllButtonText:SetTextColor( api.GRAY_FONT_COLOR.r, api.GRAY_FONT_COLOR.g, api.GRAY_FONT_COLOR.b )
|
||||
api.SendMailMoneyText:SetText( api.COD_AMOUNT )
|
||||
end
|
||||
else
|
||||
api.SendMailSendMoneyButton:SetChecked( 1 )
|
||||
api.SendMailCODButton:SetChecked( nil )
|
||||
api.SendMailMoneyText:SetText( api.AMOUNT_TO_SEND )
|
||||
api.SendMailCODButton:Disable()
|
||||
api.SendMailCODButtonText:SetTextColor( api.GRAY_FONT_COLOR.r, api.GRAY_FONT_COLOR.g, api.GRAY_FONT_COLOR.b )
|
||||
api.SendMailCODAllButton:Disable()
|
||||
api.SendMailCODAllButtonText:SetTextColor( api.GRAY_FONT_COLOR.r, api.GRAY_FONT_COLOR.g, api.GRAY_FONT_COLOR.b )
|
||||
end
|
||||
|
||||
api.MoneyFrame_Update( "SendMailCostMoneyFrame", api.GetSendMailPrice() * math.max( 1, SendMail_NumAttachments() ) )
|
||||
|
||||
-- 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 api.SendMailFrame.maxRowsShown and last > 0 and itemRowCount < api.SendMailFrame.maxRowsShown then
|
||||
itemRowCount = api.SendMailFrame.maxRowsShown
|
||||
else
|
||||
api.SendMailFrame.maxRowsShown = itemRowCount
|
||||
end
|
||||
|
||||
-- Compute sizes
|
||||
local cursorx = 0
|
||||
local cursory = itemRowCount - 1
|
||||
local marginxl = 8 + 6
|
||||
local marginxr = 40 + 6
|
||||
local areax = api.SendMailFrame:GetWidth() - marginxl - marginxr
|
||||
local iconx = api.MailAttachment1:GetWidth() + 2
|
||||
local icony = api.MailAttachment1:GetHeight() + 2
|
||||
local gapx1 = api.floor( (areax - (iconx * ATTACHMENTS_PER_ROW_SEND)) / (ATTACHMENTS_PER_ROW_SEND - 1) )
|
||||
local gapx2 = api.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
|
||||
|
||||
api.MailHorizontalBarLeft:SetPoint( "TOPLEFT", api.SendMailFrame, "BOTTOMLEFT", 2 + 15, 184 + areay - 14 )
|
||||
|
||||
api.SendMailScrollFrame:SetHeight( scrollHeight )
|
||||
api.SendMailScrollChildFrame:SetHeight( scrollHeight )
|
||||
|
||||
local SendMailScrollFrameTop = ({ api.SendMailScrollFrame:GetRegions() })[ 3 ]
|
||||
SendMailScrollFrameTop:SetHeight( scrollHeight )
|
||||
SendMailScrollFrameTop:SetTexCoord( 0, .484375, 0, scrollHeight / 256 )
|
||||
|
||||
api.StationeryBackgroundLeft:SetHeight( scrollHeight )
|
||||
api.StationeryBackgroundLeft:SetTexCoord( 0, 1, 0, scrollHeight / 256 )
|
||||
|
||||
|
||||
api.StationeryBackgroundRight:SetHeight( scrollHeight )
|
||||
api.StationeryBackgroundRight:SetTexCoord( 0, 1, 0, scrollHeight / 256 )
|
||||
|
||||
-- Set Items
|
||||
for i = 1, ATTACHMENTS_MAX do
|
||||
if cursory >= 0 then
|
||||
api[ "MailAttachment" .. i ]:Enable()
|
||||
api[ "MailAttachment" .. i ]:Show()
|
||||
api[ "MailAttachment" .. 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
|
||||
api[ "MailAttachment" .. i ]:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
api.SendMailFrame_CanSend()
|
||||
end
|
||||
|
||||
function m.hook.SendMailRadioButton_OnClick( index )
|
||||
if (index == 1) then
|
||||
api.SendMailSendMoneyButton:SetChecked( 1 );
|
||||
api.SendMailCODButton:SetChecked( nil );
|
||||
api.SendMailMoneyText:SetText( api.AMOUNT_TO_SEND );
|
||||
api.SendMailCODAllButton:Disable()
|
||||
api.SendMailCODAllButtonText:SetTextColor( api.GRAY_FONT_COLOR.r, api.GRAY_FONT_COLOR.g, api.GRAY_FONT_COLOR.b )
|
||||
else
|
||||
api.SendMailSendMoneyButton:SetChecked( nil );
|
||||
api.SendMailCODButton:SetChecked( 1 );
|
||||
api.SendMailMoneyText:SetText( api.COD_AMOUNT );
|
||||
|
||||
if SendMail_NumAttachments() > 1 then
|
||||
api.SendMailCODAllButton:Enable()
|
||||
api.SendMailCODAllButtonText:SetTextColor( api.NORMAL_FONT_COLOR.r, api.NORMAL_FONT_COLOR.g, api.NORMAL_FONT_COLOR.b )
|
||||
m.set_cod_text()
|
||||
end
|
||||
end
|
||||
api.PlaySound( "igMainMenuOptionCheckBoxOn" );
|
||||
end
|
||||
|
||||
function m.hook.ClickSendMailItemButton()
|
||||
SendMail_SetAttachment( GetCursorItem() )
|
||||
end
|
||||
|
||||
function m.hook.GetContainerItemInfo( bag, slot )
|
||||
local ret = pack( orig.GetContainerItemInfo( bag, slot ) )
|
||||
ret[ 3 ] = ret[ 3 ] or SendMail_Attached( bag, slot ) and 1 or nil
|
||||
return unpack( ret )
|
||||
end
|
||||
|
||||
function m.hook.PickupContainerItem( bag, slot )
|
||||
if SendMail_Attached( bag, slot ) then return end
|
||||
if api.GetContainerItemInfo( bag, slot ) then SetCursorItem( { bag, slot } ) end
|
||||
return orig.PickupContainerItem( bag, slot )
|
||||
end
|
||||
|
||||
function m.hook.SplitContainerItem( bag, slot, amount )
|
||||
if SendMail_Attached( bag, slot ) then return end
|
||||
return orig.SplitContainerItem( bag, slot, amount )
|
||||
end
|
||||
|
||||
function m.hook.UseContainerItem( bag, slot, onself )
|
||||
if SendMail_Attached( bag, slot ) then return end
|
||||
if api.IsShiftKeyDown() or api.IsControlKeyDown() or api.IsAltKeyDown() then
|
||||
return orig.UseContainerItem( bag, slot, onself )
|
||||
elseif api.MailFrame:IsVisible() then
|
||||
api.MailFrameTab_OnClick( 2 )
|
||||
SendMail_SetAttachment { bag, slot }
|
||||
elseif api.TradeFrame:IsVisible() then
|
||||
for i = 1, 6 do
|
||||
if not api.GetTradePlayerItemLink( i ) then
|
||||
orig.PickupContainerItem( bag, slot )
|
||||
api.ClickTradeButton( i )
|
||||
return
|
||||
end
|
||||
end
|
||||
else
|
||||
return orig.UseContainerItem( bag, slot, onself )
|
||||
end
|
||||
end
|
||||
|
||||
function m.hook.SendMailFrame_CanSend()
|
||||
if not SendMail_sending and string.len( api.SendMailNameEditBox:GetText() ) > 0 and (api.SendMailSendMoneyButton:GetChecked() and api.MoneyInputFrame_GetCopper( api.SendMailMoney ) or 0) + api.GetSendMailPrice() * math.max( 1, SendMail_NumAttachments() ) <= api.GetMoney() then
|
||||
MailMailButton:Enable()
|
||||
else
|
||||
MailMailButton:Disable()
|
||||
end
|
||||
end
|
||||
|
||||
function MailMailButton_OnClick()
|
||||
api.MailAutoCompleteBox:Hide()
|
||||
|
||||
api.TurtleMail_To = api.SendMailNameEditBox:GetText()
|
||||
api.SendMailNameEditBox:HighlightText()
|
||||
|
||||
SendMail_state = {
|
||||
to = api.TurtleMail_To,
|
||||
subject = MailSubjectEditBox:GetText(),
|
||||
body = api.SendMailBodyEditBox:GetText(),
|
||||
money = api.MoneyInputFrame_GetCopper( api.SendMailMoney ),
|
||||
cod = api.SendMailCODButton:GetChecked(),
|
||||
attachments = SendMail_Attachments(),
|
||||
numMessages = math.max( 1, SendMail_NumAttachments() ),
|
||||
}
|
||||
|
||||
SendMail_Clear()
|
||||
SendMail_sending = true
|
||||
SendMail_Send()
|
||||
end
|
||||
|
||||
function SendMail_Load()
|
||||
api.SendMailFrame:CreateTexture( "MailHorizontalBarLeft", "BACKGROUND" )
|
||||
api.SendMailFrame:CreateTexture( "MailHorizontalBarRight", "BACKGROUND" )
|
||||
---@diagnostic disable-next-line: undefined-global
|
||||
if not pfUI or not pfUI.version then
|
||||
api.MailHorizontalBarLeft:SetTexture( [[Interface\ClassTrainerFrame\UI-ClassTrainer-HorizontalBar]] )
|
||||
api.MailHorizontalBarLeft:SetWidth( 256 )
|
||||
api.MailHorizontalBarLeft:SetHeight( 16 )
|
||||
api.MailHorizontalBarLeft:SetTexCoord( 0, 1, 0, .25 )
|
||||
|
||||
api.MailHorizontalBarRight:SetTexture( [[Interface\ClassTrainerFrame\UI-ClassTrainer-HorizontalBar]] )
|
||||
api.MailHorizontalBarRight:SetWidth( 75 )
|
||||
api.MailHorizontalBarRight:SetHeight( 16 )
|
||||
api.MailHorizontalBarRight:SetTexCoord( 0, .29296875, .25, .5 )
|
||||
api.MailHorizontalBarRight:SetPoint( "LEFT", api.MailHorizontalBarLeft, "RIGHT" )
|
||||
end
|
||||
|
||||
do
|
||||
local background = ({ api.SendMailPackageButton:GetRegions() })[ 1 ]
|
||||
background:Hide()
|
||||
local count = ({ api.SendMailPackageButton:GetRegions() })[ 3 ]
|
||||
count:Hide()
|
||||
api.SendMailPackageButton:Disable()
|
||||
api.SendMailPackageButton:SetScript( "OnReceiveDrag", nil )
|
||||
api.SendMailPackageButton:SetScript( "OnDragStart", nil )
|
||||
end
|
||||
|
||||
api.SendMailMoneyText:SetJustifyH( "LEFT" )
|
||||
api.SendMailMoneyText:SetPoint( "TOPLEFT", 0, 0 )
|
||||
api.SendMailMoney:ClearAllPoints()
|
||||
api.SendMailMoney:SetPoint( "TOPLEFT", api.SendMailMoneyText, "BOTTOMLEFT", 5, -5 )
|
||||
api.SendMailMoneyGoldRight:SetPoint( "RIGHT", 20, 0 )
|
||||
do ({ api.SendMailMoneyGold:GetRegions() })[ 9 ]:SetDrawLayer( "BORDER" ) end
|
||||
api.SendMailMoneyGold:SetMaxLetters( 7 )
|
||||
api.SendMailMoneyGold:SetWidth( 50 )
|
||||
api.SendMailMoneySilverRight:SetPoint( "RIGHT", 10, 0 )
|
||||
do ({ api.SendMailMoneySilver:GetRegions() })[ 9 ]:SetDrawLayer( "BORDER" ) end
|
||||
api.SendMailMoneySilver:SetWidth( 28 )
|
||||
api.SendMailMoneySilver:SetPoint( "LEFT", api.SendMailMoneyGold, "RIGHT", 30, 0 )
|
||||
api.SendMailMoneyCopperRight:SetPoint( "RIGHT", 10, 0 )
|
||||
do ({ api.SendMailMoneyCopper:GetRegions() })[ 9 ]:SetDrawLayer( "BORDER" ) end
|
||||
api.SendMailMoneyCopper:SetWidth( 28 )
|
||||
api.SendMailMoneyCopper:SetPoint( "LEFT", api.SendMailMoneySilver, "RIGHT", 20, 0 )
|
||||
api.SendMailSendMoneyButton:SetPoint( "TOPLEFT", api.SendMailMoney, "TOPRIGHT", 0, 12 )
|
||||
|
||||
-- hack to avoid automatic subject setting and button disabling from weird blizzard code
|
||||
MailMailButton = api.SendMailMailButton
|
||||
api.SendMailMailButton = setmetatable( {}, { __index = function() return function() end end } )
|
||||
api.SendMailMailButton_OnClick = MailMailButton_OnClick
|
||||
MailSubjectEditBox = api.SendMailSubjectEditBox
|
||||
api.SendMailSubjectEditBox = setmetatable( {}, {
|
||||
__index = function( _, key )
|
||||
return function( _, ... )
|
||||
return MailSubjectEditBox[ key ]( MailSubjectEditBox, unpack( arg ) )
|
||||
end
|
||||
end,
|
||||
} )
|
||||
|
||||
api.SendMailNameEditBox._SetText = api.SendMailNameEditBox.SetText
|
||||
function api.SendMailNameEditBox:SetText( ... )
|
||||
if not api.TurtleMail_To then
|
||||
return self:_SetText( unpack( arg ) )
|
||||
end
|
||||
end
|
||||
|
||||
api.SendMailNameEditBox:SetScript( "OnShow", function()
|
||||
if api.TurtleMail_To then
|
||||
api.this:_SetText( api.TurtleMail_To )
|
||||
end
|
||||
end )
|
||||
api.SendMailNameEditBox:SetScript( "OnChar", function()
|
||||
api.TurtleMail_To = nil
|
||||
GetSuggestions()
|
||||
end )
|
||||
api.SendMailNameEditBox:SetScript( "OnTabPressed", function()
|
||||
if api.MailAutoCompleteBox:IsVisible() then
|
||||
if api.IsShiftKeyDown() then
|
||||
PreviousMatch()
|
||||
else
|
||||
NextMatch()
|
||||
end
|
||||
else
|
||||
MailSubjectEditBox:SetFocus()
|
||||
end
|
||||
end )
|
||||
api.SendMailNameEditBox:SetScript( "OnEnterPressed", function()
|
||||
if api.MailAutoCompleteBox:IsVisible() then
|
||||
api.MailAutoCompleteBox:Hide()
|
||||
this:HighlightText( 0, 0 )
|
||||
else
|
||||
MailSubjectEditBox:SetFocus()
|
||||
end
|
||||
end )
|
||||
api.SendMailNameEditBox:SetScript( "OnEscapePressed", function()
|
||||
if api.MailAutoCompleteBox:IsVisible() then
|
||||
api.MailAutoCompleteBox:Hide()
|
||||
else
|
||||
this:ClearFocus()
|
||||
end
|
||||
end )
|
||||
function api.SendMailNameEditBox.focusLoss()
|
||||
api.MailAutoCompleteBox:Hide()
|
||||
end
|
||||
|
||||
api.SendMailCODAllButton:SetScript( "OnClick", function()
|
||||
m.set_cod_text()
|
||||
end )
|
||||
|
||||
do
|
||||
local orig_script = api.SendMailNameEditBox:GetScript( "OnTextChanged" )
|
||||
api.SendMailNameEditBox:SetScript( "OnTextChanged", function()
|
||||
local text = this:GetText()
|
||||
local formatted = string.gsub( string.lower( text ), "^%l", string.upper )
|
||||
if text ~= formatted then
|
||||
this:SetText( formatted )
|
||||
end
|
||||
return orig_script()
|
||||
end )
|
||||
end
|
||||
|
||||
for _, editBox in { api.SendMailNameEditBox, api.SendMailSubjectEditBox } do
|
||||
editBox:SetScript( "OnEditFocusGained", function()
|
||||
this:HighlightText()
|
||||
end )
|
||||
editBox:SetScript( "OnEditFocusLost", function()
|
||||
(this.focusLoss or function() end)()
|
||||
this:HighlightText( 0, 0 )
|
||||
end )
|
||||
do
|
||||
local lastClick
|
||||
editBox:SetScript( "OnMouseDown", function()
|
||||
local x, y = api.GetCursorPosition()
|
||||
if lastClick and api.GetTime() - lastClick.t < .5 and x == lastClick.x and y == lastClick.y then
|
||||
this:SetScript( "OnUpdate", function()
|
||||
this:HighlightText()
|
||||
this:SetScript( "OnUpdate", nil )
|
||||
end )
|
||||
end
|
||||
lastClick = { t = api.GetTime(), x = x, y = y }
|
||||
end )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function SendMail_Attached( bag, slot )
|
||||
if not api.MailFrame:IsVisible() then return false end
|
||||
for i = 1, ATTACHMENTS_MAX do
|
||||
local btn = api[ "MailAttachment" .. i ]
|
||||
if btn.item and btn.item[ 1 ] == bag and btn.item[ 2 ] == slot then
|
||||
return true
|
||||
end
|
||||
end
|
||||
if SendMail_state then
|
||||
for _, attachment in SendMail_state.attachments do
|
||||
if attachment[ 1 ] == bag and attachment[ 2 ] == slot then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function m.AttachmentButton_OnClick()
|
||||
local attachedItem = this.item
|
||||
local cursorItem = GetCursorItem()
|
||||
if SendMail_SetAttachment( cursorItem, this ) then
|
||||
if attachedItem then
|
||||
if arg1 == "LeftButton" then SetCursorItem( attachedItem ) end
|
||||
orig.PickupContainerItem( unpack( attachedItem ) )
|
||||
if arg1 ~= "LeftButton" then api.ClearCursor() end -- for the lock changed event
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- requires an item lock changed event for a proper update
|
||||
function SendMail_SetAttachment( item, slot )
|
||||
if item and not SendMail_PickupMailable( item ) then
|
||||
api.ClearCursor()
|
||||
return
|
||||
elseif not slot then
|
||||
for i = 1, ATTACHMENTS_MAX do
|
||||
if not api[ "MailAttachment" .. i ].item then
|
||||
slot = api[ "MailAttachment" .. i ]
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if slot then
|
||||
if not (item or slot.item) then return true end
|
||||
slot.item = item
|
||||
api.ClearCursor()
|
||||
api.SendMailFrame_Update()
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function SendMail_PickupMailable( item )
|
||||
api.ClearCursor()
|
||||
orig.ClickSendMailItemButton()
|
||||
api.ClearCursor()
|
||||
orig.PickupContainerItem( unpack( item ) )
|
||||
orig.ClickSendMailItemButton()
|
||||
local mailable = api.GetSendMailItem() and true or false
|
||||
orig.ClickSendMailItemButton()
|
||||
return mailable
|
||||
end
|
||||
|
||||
function SendMail_NumAttachments()
|
||||
local x = 0
|
||||
for i = 1, ATTACHMENTS_MAX do
|
||||
if api[ "MailAttachment" .. i ].item then
|
||||
x = x + 1
|
||||
end
|
||||
end
|
||||
return x
|
||||
end
|
||||
|
||||
function SendMail_Attachments()
|
||||
local t = {}
|
||||
for i = 1, ATTACHMENTS_MAX do
|
||||
local btn = api[ "MailAttachment" .. i ]
|
||||
if btn.item then
|
||||
table.insert( t, btn.item )
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
function SendMail_Clear()
|
||||
local anyItem
|
||||
for i = 1, ATTACHMENTS_MAX do
|
||||
anyItem = anyItem or api[ "MailAttachment" .. i ].item
|
||||
api[ "MailAttachment" .. i ].item = nil
|
||||
end
|
||||
if anyItem then
|
||||
api.ClearCursor()
|
||||
api.PickupContainerItem( unpack( anyItem ) )
|
||||
api.ClearCursor()
|
||||
end
|
||||
MailMailButton:Disable()
|
||||
api.SendMailNameEditBox:SetText ""
|
||||
api.SendMailNameEditBox:SetFocus()
|
||||
MailSubjectEditBox:SetText ""
|
||||
api.SendMailBodyEditBox:SetText ""
|
||||
api.MoneyInputFrame_ResetMoney( api.SendMailMoney )
|
||||
api.SendMailRadioButton_OnClick( 1 )
|
||||
|
||||
api.SendMailFrame_Update()
|
||||
end
|
||||
|
||||
function SendMail_Send()
|
||||
local item = table.remove( SendMail_state.attachments, 1 )
|
||||
if item then
|
||||
api.ClearCursor()
|
||||
orig.ClickSendMailItemButton()
|
||||
api.ClearCursor()
|
||||
orig.PickupContainerItem( unpack( item ) )
|
||||
orig.ClickSendMailItemButton()
|
||||
|
||||
if not api.GetSendMailItem() then
|
||||
api.DEFAULT_CHAT_FRAME:AddMessage( "|cffabd473TurtleMail|r: " .. api.ERROR_CAPS, 1, 0, 0 )
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local amount = SendMail_state.money
|
||||
if amount > 0 then
|
||||
if not api.SendMailCODAllButton:GetChecked() then
|
||||
SendMail_state.money = 0
|
||||
end
|
||||
if SendMail_state.cod then
|
||||
api.SetSendMailCOD( amount )
|
||||
else
|
||||
SendMail_state.money = 0
|
||||
api.SetSendMailMoney( amount )
|
||||
end
|
||||
end
|
||||
|
||||
local subject = SendMail_state.subject
|
||||
if subject == "" then
|
||||
if item then
|
||||
local itemName, itemTexture, stackCount, quality = api.GetSendMailItem()
|
||||
subject = itemName .. (stackCount > 1 and " (" .. stackCount .. ")" or "")
|
||||
else
|
||||
subject = "<" .. api.NO_ATTACHMENTS .. ">"
|
||||
end
|
||||
elseif SendMail_state.numMessages > 1 then
|
||||
subject = subject ..
|
||||
string.format( " [%d/%d]", SendMail_state.numMessages - getn( SendMail_state.attachments ),
|
||||
SendMail_state.numMessages )
|
||||
end
|
||||
|
||||
api.SendMail( SendMail_state.to, subject, SendMail_state.body )
|
||||
|
||||
if getn( SendMail_state.attachments ) == 0 then
|
||||
SendMail_sending = false
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local inputLength
|
||||
local matches = {}
|
||||
local index
|
||||
|
||||
local function complete()
|
||||
api.SendMailNameEditBox:SetText( matches[ index ] )
|
||||
api.SendMailNameEditBox:HighlightText( inputLength, -1 )
|
||||
for i = 1, api.MAIL_AUTOCOMPLETE_MAX_BUTTONS do
|
||||
local button = api[ "MailAutoCompleteButton" .. i ]
|
||||
if i == index then
|
||||
button:LockHighlight()
|
||||
else
|
||||
button:UnlockHighlight()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PreviousMatch()
|
||||
if index then
|
||||
index = index > 1 and index - 1 or getn( matches )
|
||||
complete()
|
||||
end
|
||||
end
|
||||
|
||||
function NextMatch()
|
||||
if index then
|
||||
---@diagnostic disable-next-line: undefined-global
|
||||
index = mod( index, getn( matches ) ) + 1
|
||||
complete()
|
||||
end
|
||||
end
|
||||
|
||||
function m.SelectMatch( i )
|
||||
index = i
|
||||
complete()
|
||||
api.MailAutoCompleteBox:Hide()
|
||||
api.SendMailNameEditBox:HighlightText( 0, 0 )
|
||||
end
|
||||
|
||||
function GetSuggestions()
|
||||
local input = api.SendMailNameEditBox:GetText()
|
||||
inputLength = string.len( input )
|
||||
|
||||
---@diagnostic disable-next-line: undefined-field
|
||||
table.setn( matches, 0 )
|
||||
index = nil
|
||||
|
||||
local autoCompleteNames = {}
|
||||
for name, time in api.TurtleMail_AutoCompleteNames[ api.GetCVar "realmName" .. "|" .. api.UnitFactionGroup "player" ] do
|
||||
table.insert( autoCompleteNames, { name = name, time = time } )
|
||||
end
|
||||
table.sort( autoCompleteNames, function( a, b ) return b.time < a.time end )
|
||||
|
||||
local ignore = { [ api.UnitName "player" ] = true }
|
||||
local function process( name )
|
||||
if name then
|
||||
if not ignore[ name ] and string.find( string.upper( name ), string.upper( input ), nil, true ) == 1 then
|
||||
table.insert( matches, name )
|
||||
end
|
||||
ignore[ name ] = true
|
||||
end
|
||||
end
|
||||
for _, t in autoCompleteNames do
|
||||
process( t.name )
|
||||
end
|
||||
for i = 1, api.GetNumFriends() do
|
||||
process( api.GetFriendInfo( i ) )
|
||||
end
|
||||
for i = 1, api.GetNumGuildMembers( true ) do
|
||||
process( api.GetGuildRosterInfo( i ) )
|
||||
end
|
||||
|
||||
---@diagnostic disable-next-line: undefined-field
|
||||
table.setn( matches, math.min( getn( matches ), api.MAIL_AUTOCOMPLETE_MAX_BUTTONS ) )
|
||||
if getn( matches ) > 0 and (getn( matches ) > 1 or input ~= matches[ 1 ]) then
|
||||
for i = 1, api.MAIL_AUTOCOMPLETE_MAX_BUTTONS do
|
||||
local button = api[ "MailAutoCompleteButton" .. i ]
|
||||
if i <= getn( matches ) then
|
||||
button:SetText( matches[ i ] )
|
||||
button:GetFontString():SetPoint( "LEFT", button, "LEFT", 15, 0 )
|
||||
button:Show()
|
||||
else
|
||||
button:Hide()
|
||||
end
|
||||
end
|
||||
api.MailAutoCompleteBox:SetHeight( getn( matches ) * api.MailAutoCompleteButton1:GetHeight() + 35 )
|
||||
api.MailAutoCompleteBox:SetWidth( 120 )
|
||||
api.MailAutoCompleteBox:Show()
|
||||
index = 1
|
||||
complete()
|
||||
else
|
||||
api.MailAutoCompleteBox:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ************
|
||||
-- Localization
|
||||
do
|
||||
local function defaultFunc( _, key )
|
||||
return key;
|
||||
end
|
||||
setmetatable( L, { __index = defaultFunc } );
|
||||
|
||||
L[ "collected" ] = nil
|
||||
L[ "1st mail" ] = nil
|
||||
L[ "each mail" ] = nil
|
||||
L[ "Money received" ] = nil
|
||||
|
||||
if api.GetLocale() == "frFR" then
|
||||
L[ "collected" ] = "collecté"
|
||||
L[ "1st mail" ] = "1er courrier"
|
||||
L[ "each mail" ] = "chaque courrier"
|
||||
L[ "Money received" ] = "Argent reçu"
|
||||
end
|
||||
|
||||
if api.GetLocale() == "esES" then
|
||||
L[ "collected" ] = "recogido"
|
||||
L[ "1st mail" ] = "1er correo"
|
||||
L[ "each mail" ] = "cada correo"
|
||||
L[ "Money received" ] = "Dinero recibido"
|
||||
end
|
||||
|
||||
if api.GetLocale() == "deDE" then
|
||||
L[ "collected" ] = "gesammelt"
|
||||
L[ "1st mail" ] = "1. Mail"
|
||||
L[ "each mail" ] = "jede Mail"
|
||||
L[ "Money received" ] = "Geld erhalten"
|
||||
end
|
||||
|
||||
if api.GetLocale() == "ruRU" then
|
||||
L[ "collected" ] = "собрано"
|
||||
L[ "1st mail" ] = "1-я почта"
|
||||
L[ "each mail" ] = "каждая почта"
|
||||
L[ "Money received" ] = "Деньги получены"
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
## Interface: 11200
|
||||
## Title: |cffabd473Turtle|cffffffffMail
|
||||
## Author: shirsig/sica
|
||||
## Version: 1.0
|
||||
## Notes: Mailbox enhancement
|
||||
## SavedVariables: TurtleMail_AutoCompleteNames
|
||||
## SavedVariablesPerCharacter: TurtleMail_To TurtleMail_Point
|
||||
|
||||
TurtleMail.xml
|
||||
@@ -1,6 +1,6 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
C:\Projects\WoW\Bin\Interface\FrameXML\UI.xsd">
|
||||
<Script file="Mail.lua"/>
|
||||
..\FrameXML\UI.xsd">
|
||||
<Script file="TurtleMail.lua"/>
|
||||
|
||||
<Button name="MailAutoCompleteButtonTemplate" virtual="true">
|
||||
<Size>
|
||||
@@ -10,9 +10,6 @@ C:\Projects\WoW\Bin\Interface\FrameXML\UI.xsd">
|
||||
<OnClick>
|
||||
Mail.SelectMatch(this:GetID())
|
||||
</OnClick>
|
||||
<OnTabPressed>
|
||||
Mail.NextMatch()
|
||||
</OnTabPressed>
|
||||
</Scripts>
|
||||
<NormalFont inherits="GameFontNormal"/>
|
||||
<HighlightFont inherits="GameFontHighlight"/>
|
||||
@@ -125,7 +122,7 @@ C:\Projects\WoW\Bin\Interface\FrameXML\UI.xsd">
|
||||
</FontString>
|
||||
</Layer>
|
||||
<Layer level="OVERLAY">
|
||||
<Texture parentKey="IconBorder" file="Interface\Common\WhiteIconFrame" hidden="true">
|
||||
<Texture parentKey="IconBorder" file="Interface\Buttons\WHITE8x8" hidden="true">
|
||||
<Size>
|
||||
<AbsDimension x="37" y="37"/>
|
||||
</Size>
|
||||
@@ -186,4 +183,39 @@ C:\Projects\WoW\Bin\Interface\FrameXML\UI.xsd">
|
||||
<Button name="MailAttachment19" parent="SendMailFrame" inherits="MailAttachment"/>
|
||||
<Button name="MailAttachment20" parent="SendMailFrame" inherits="MailAttachment"/>
|
||||
<Button name="MailAttachment21" parent="SendMailFrame" inherits="MailAttachment"/>
|
||||
|
||||
<CheckButton name="SendMailCODAllButton" parent="SendMailFrame" inherits="OptionsCheckButtonTemplate" >
|
||||
<Size x="16" y="16"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="SendMailCODButton" relativePoint="TOPRIGHT">
|
||||
<Offset>
|
||||
<AbsDimension x="40" y="0"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
getglobal(this:GetName().."Text"):SetText(" All mails");
|
||||
</OnLoad>
|
||||
</Scripts>
|
||||
</CheckButton>
|
||||
|
||||
<Frame parent="InboxFrame" >
|
||||
<Layers>
|
||||
<Layer level="ARTWORK">
|
||||
<FontString name="MoneyReceived" inherits="GameFontNormal" text="Money received:" hidden="true">
|
||||
<Size>
|
||||
<AbsDimension x="224" y="14"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="InboxTitleText" relativePoint="BOTTOMLEFT">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="-5"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
</Layer>
|
||||
</Layers>
|
||||
</Frame>
|
||||
</Ui>
|
||||
Reference in New Issue
Block a user