Wednesday, April 18, 2012

MailFrame.xml

So I'm creating a notepad type addon, and I'm trying to add a feature in which you can save mail messages, which will be sent the next time you open the mailbox frame. I've gotten to the point where the fields are full and the correct information entered in, but when I try to use "WPad_SendMailMailButton_OnClick()" I get an error in the first line of the method, "this:Disable()". I'm not sure if it's because I need to hook into the function or something, or it the button can't be disabled because it wasn't clicked, but any help would be appreciated.|||Well, it sounds like the "this" object doesn't have the "Disable" method. How are you calling the "WPad_SendMailMailButton_OnClick()" method and what are you trying to disable?

If you are using OnEvent or OnUpdate on a frame (such as your frame to check if the mail window is open), and you call the "WPad_ ... _ OnClick()" method from inside that code, "this" will refer to the object that generated the method, so your frame that you are using will be "this" and if it doesn't have a "Disable" method, it will error.

Or, do you have a button on your addon, let's assume it is called "SendMailMailButton" and when you click the button, the button's "OnClick" method is the method we are talking about?

... more info please. When and where do you call this method?|||When you initially write out your message, if the mail frame is open, then it will just send the mail, otherwise it will be saved to a table. Then I use an OnEvent():


Code:
function WPad_OnEvent()
if(event=="ADDON_LOADED" or event=="VARIABLES_LOADED") then
if(arg1=="WoWPad") then
DebugOut("Event: WoWPad Loaded"); WP_BMARKTEXTS={WPadBookmarks_Bmark1,WPadBookmarks_Bmark2,WPadBookmarks_Bmark3,WPadBookmarks_Bmark4,WPadBookmarks_Bmark5};
WPad_restoreVisuals();
end
elseif(event=="MAIL_SHOW") then
WPad_SendQueuedMail();
Out("WoWPad: Queued Mail Sent.");
end

function WPad_SendQueuedMail()
for i=1,#WP_MAILTONAMES do
if(MailFrame:IsVisible()) then
MailFrameTab_OnClick(2);
SendMailNameEditBox:SetText(WP_MAILTONAMES[i]);
SendMailSubjectEditBox:SetText(WP_MAILTOSUBJECTS[i]);
SendMailBodyEditBox:SetText(WP_MAILTOBODIES[i]);
WPad_SendMailMailButton_OnClick();
else
UIErrorsFrame:AddMessage("Mailbox not open", 1, 0, 0, 1.0, UIERRORS_HOLD_TIME);
end
end
end

function WPad_SendMailMailButton_OnClick()

this:Disable();
local copper = MoneyInputFrame_GetCopper(SendMailMoney);
SetSendMailCOD(0);
SetSendMailMoney(0);
if ( SendMailSendMoneyButton:GetChecked() ) then
-- Send Money
if ( copper > 0 ) then
-- Open confirmation dialog
StaticPopup_Show("SEND_MONEY", SendMailNameEditBox:GetText());
return;
end
else
-- Send C.O.D.
if ( copper > 0 ) then
SetSendMailCOD(copper);
end
end
SendMailFrame_SendMail();
end

Not sure if I even have to hook the function, because I'm not changing it. But I haven't really dealt with the Blizz frames in RaidRogue, so this is new to me.|||Well, if your "WPad_SendMailMailButton_OnClick" method is basically a copy of the original "SendMailMailButton_OnClick" method, just with a few things added, change the "this:Disable()" line to:

SendMailMailButton:Disable();

or

getglobal(SendMailMailButton"):Disable();



The problem is what I suspected. When you call the method "WPad_SendMailMailButton_OnClick" in your code, you are not calling it from the UI's send mail button, but from your addon's OnEvent method. The problem is that the code you have was taken from the "OnClick" code of the send mail button. When you click the button, "this" will refer to the button that you are interacting with. Since it is a button, "this" also has all the methods of a button, so this:Disable() exists and will disable the send mail button.

What is happening in your case is that your frame that handles the events is calling the OnClick method. When that happens, the "this" variable will point to the original object that the method originated from, which is your WPad frame. Your WPad frame is NOT a button, so it doesn't have the "disable" method and is generating the error. Your code is not disabling the send mail button, it's trying to disable your frame, and your frame doesn't have that ability, hence the error.

I hope that makes since with how the "this" variable works? :)|||I changed the line from this, to getglobal("SendMailMailButton"), which got rid of the error, but now the window just sits there. It adds all three fields correctly, but does not send the mail. I'm beginning to think Blizzard want it to be done automatically, but I'm not sure.|||I should have realized this. Well, if you want to send mail, just do this:

1) Wait for mail box to open, or a mail to have been sent (use an event, like you already have. You already registered the mail opening. Also register "MAIL_SEND_SUCCESS" for mail sending success)

2) Use the SendMail API to send a mail. This will be in the event handler, like above:


Code:
-- SendMail(target, subject, mailBody) -- This is the way it works
-- So, use this code:
if (table.getn(MAILTONAMES) > 0) then
SendMail(MAILTONAMES[1], MAILTOSUBJECTS[1], MAILTOBODIES[1]); -- send first entry
table.remove(MAILTONAMES, 1); -- remove first entry (thus making #2 entry your new #1 entry)
table.remove(MAILTOSUBJECTS, 1); -- remove first entry
table.remove(MAILTOBODIES, 1); -- remove first entry
end

3) Since this will only send mail if there are entries in your MAILTONAMES table, it will iterate through each mail and send it. You can't send another mail until either the mail success event or the mail fail event ("MAIL_FAILED") fires. So, this will work as a throttle. If you try to send mail before either of these events happen, it won't do anything.

So, your revised code could be ...


Code:
function WPad_OnEvent()
if(event=="ADDON_LOADED" or event=="VARIABLES_LOADED") then
if(arg1=="WoWPad") then
DebugOut("Event: WoWPad Loaded");
WP_BMARKTEXTS={WPadBookmarks_Bmark1, WPadBookmarks_Bmark2, WPadBookmarks_Bmark3, WPadBookmarks_Bmark4, WPadBookmarks_Bmark5};
WPad_restoreVisuals();
this:RegisterEvent("MAIL_SEND_SUCCESS");
end
elseif ((event=="MAIL_SHOW") or (event=="MAIL_SEND_SUCCESS")) then
if (table.getn(MAILTONAMES) > 0) then
SendMail(MAILTONAMES[1], MAILTOSUBJECTS[1], MAILTOBODIES[1]); -- send first entry
table.remove(MAILTONAMES, 1); -- remove first entry (thus making #2 entry your new #1 entry)
table.remove(MAILTOSUBJECTS, 1); -- remove first entry
table.remove(MAILTOBODIES, 1); -- remove first entry
else
Out("WoWPad: Queued Mail Sent.");
end
end
end

No comments:

Post a Comment