diff options
Diffstat (limited to 'linden/indra/newview/llnotify.cpp')
-rw-r--r-- | linden/indra/newview/llnotify.cpp | 215 |
1 files changed, 159 insertions, 56 deletions
diff --git a/linden/indra/newview/llnotify.cpp b/linden/indra/newview/llnotify.cpp index 7822d00..4f5c64b 100644 --- a/linden/indra/newview/llnotify.cpp +++ b/linden/indra/newview/llnotify.cpp | |||
@@ -58,48 +58,106 @@ const F32 ANIMATION_TIME = 0.333f; | |||
58 | S32 LLNotifyBox::sNotifyBoxCount = 0; | 58 | S32 LLNotifyBox::sNotifyBoxCount = 0; |
59 | const LLFontGL* LLNotifyBox::sFont = NULL; | 59 | const LLFontGL* LLNotifyBox::sFont = NULL; |
60 | const LLFontGL* LLNotifyBox::sFontSmall = NULL; | 60 | const LLFontGL* LLNotifyBox::sFontSmall = NULL; |
61 | std::map<LLString, LLNotifyBox*> LLNotifyBox::sOpenUniqueNotifyBoxes; | ||
62 | LLPointer<LLNotifyBoxTemplate> LLNotifyBox::sDefaultTemplate; | ||
63 | |||
61 | 64 | ||
62 | LLNotifyBox::template_map_t LLNotifyBox::sNotifyTemplates; | 65 | LLNotifyBox::template_map_t LLNotifyBox::sNotifyTemplates; |
63 | 66 | ||
67 | LLNotifyBox::LLNotifyBehavior::LLNotifyBehavior(notify_callback_t callback, void* data) : | ||
68 | mCallback(callback), | ||
69 | mData(data) | ||
70 | { | ||
71 | } | ||
72 | |||
64 | //--------------------------------------------------------------------------- | 73 | //--------------------------------------------------------------------------- |
65 | // LLNotifyBox | 74 | // LLNotifyBox |
66 | //--------------------------------------------------------------------------- | 75 | //--------------------------------------------------------------------------- |
67 | 76 | ||
68 | //static | 77 | //static |
69 | void LLNotifyBox::showXml( const LLString& xml_desc, notify_callback_t callback, void *user_data) | 78 | LLNotifyBox* LLNotifyBox::showXml( const LLString& xml_desc, notify_callback_t callback, void *user_data) |
70 | { | 79 | { |
71 | return showXml(xml_desc, LLString::format_map_t(), callback, user_data); | 80 | return showXml(xml_desc, LLString::format_map_t(), callback, user_data); |
72 | } | 81 | } |
73 | 82 | ||
74 | 83 | ||
75 | //static | 84 | //static |
76 | void LLNotifyBox::showXml( const LLString& xml_desc, const LLString::format_map_t& args, BOOL is_caution, | 85 | LLNotifyBox* LLNotifyBox::showXml( const LLString& xml_desc, const LLString::format_map_t& args, BOOL is_caution, |
77 | notify_callback_t callback, void *user_data) | 86 | notify_callback_t callback, void *user_data) |
78 | { | 87 | { |
79 | // for script permission prompts | 88 | // for script permission prompts |
80 | LLNotifyBox* notify = new LLNotifyBox(xml_desc, args, callback, user_data, is_caution); | 89 | LLPointer<LLNotifyBoxTemplate> xml_template = getTemplate(xml_desc); |
81 | gNotifyBoxView->addChild(notify); | 90 | LLNotifyBox* notify = findExistingNotify(xml_template, args); |
91 | if (notify) | ||
92 | { | ||
93 | delete notify->mBehavior; | ||
94 | notify->mBehavior = new LLNotifyBehavior(callback, user_data); | ||
95 | } | ||
96 | else | ||
97 | { | ||
98 | LLNotifyBox* notify = new LLNotifyBox(xml_template, args, callback, user_data, is_caution); | ||
99 | gNotifyBoxView->addChildAtEnd(notify); | ||
100 | notify->moveToBack(); | ||
101 | } | ||
102 | return notify; | ||
82 | } | 103 | } |
83 | 104 | ||
84 | //static | 105 | //static |
85 | void LLNotifyBox::showXml( const LLString& xml_desc, const LLString::format_map_t& args, | 106 | LLNotifyBox* LLNotifyBox::showXml( const LLString& xml_desc, const LLString::format_map_t& args, |
86 | notify_callback_t callback, void *user_data) | 107 | notify_callback_t callback, void *user_data) |
87 | { | 108 | { |
88 | LLNotifyBox* notify = new LLNotifyBox(xml_desc, args, callback, user_data); | 109 | LLPointer<LLNotifyBoxTemplate> xml_template = getTemplate(xml_desc); |
89 | gNotifyBoxView->addChild(notify); | 110 | LLNotifyBox* notify = findExistingNotify(xml_template, args); |
111 | if (notify) | ||
112 | { | ||
113 | delete notify->mBehavior; | ||
114 | notify->mBehavior = new LLNotifyBehavior(callback, user_data); | ||
115 | } | ||
116 | else | ||
117 | { | ||
118 | notify = new LLNotifyBox(xml_template, args, callback, user_data); | ||
119 | gNotifyBoxView->addChildAtEnd(notify); | ||
120 | notify->moveToBack(); | ||
121 | } | ||
122 | return notify; | ||
90 | } | 123 | } |
91 | 124 | ||
92 | //static | 125 | //static |
93 | void LLNotifyBox::showXml( const LLString& xml_desc, const LLString::format_map_t& args, | 126 | LLNotifyBox* LLNotifyBox::showXml( const LLString& xml_desc, const LLString::format_map_t& args, |
94 | notify_callback_t callback, void *user_data, | 127 | notify_callback_t callback, void *user_data, |
95 | const option_list_t& options, | 128 | const option_list_t& options, |
96 | BOOL layout_script_dialog) | 129 | BOOL layout_script_dialog) |
97 | { | 130 | { |
98 | LLNotifyBox* notify = new LLNotifyBox(xml_desc, args, callback, user_data, FALSE, options, layout_script_dialog); | 131 | LLPointer<LLNotifyBoxTemplate> xml_template = getTemplate(xml_desc); |
99 | gNotifyBoxView->addChild(notify); | 132 | LLNotifyBox* notify = findExistingNotify(xml_template, args); |
133 | if (notify) | ||
134 | { | ||
135 | delete notify->mBehavior; | ||
136 | notify->mBehavior = new LLNotifyBehavior(callback, user_data); | ||
137 | } | ||
138 | else | ||
139 | { | ||
140 | notify = new LLNotifyBox(xml_template, args, callback, user_data, FALSE, options, layout_script_dialog); | ||
141 | gNotifyBoxView->addChild(notify); | ||
142 | } | ||
143 | return notify; | ||
100 | } | 144 | } |
101 | 145 | ||
102 | LLPointer<LLNotifyBoxTemplate> LLNotifyBox::sDefaultTemplate; | 146 | //static |
147 | LLNotifyBox* LLNotifyBox::findExistingNotify(LLPointer<LLNotifyBoxTemplate> notify_template, const LLString::format_map_t &args) | ||
148 | { | ||
149 | if(notify_template->mUnique) | ||
150 | { | ||
151 | LLString message = notify_template->mMessage; | ||
152 | LLAlertDialog::format(message, args); | ||
153 | unique_map_t::iterator found_it = sOpenUniqueNotifyBoxes.find(notify_template->mLabel + message); | ||
154 | if (found_it != sOpenUniqueNotifyBoxes.end()) | ||
155 | { | ||
156 | return found_it->second; | ||
157 | } | ||
158 | } | ||
159 | return NULL; | ||
160 | } | ||
103 | 161 | ||
104 | void LLNotifyBox::cleanup() | 162 | void LLNotifyBox::cleanup() |
105 | { | 163 | { |
@@ -108,18 +166,17 @@ void LLNotifyBox::cleanup() | |||
108 | 166 | ||
109 | //--------------------------------------------------------------------------- | 167 | //--------------------------------------------------------------------------- |
110 | 168 | ||
111 | LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t& args, | 169 | LLNotifyBox::LLNotifyBox(LLPointer<LLNotifyBoxTemplate> xml_template, const LLString::format_map_t& args, |
112 | notify_callback_t callback, void* user_data, BOOL is_caution, | 170 | notify_callback_t callback, void* user_data, BOOL is_caution, |
113 | const option_list_t& extra_options, | 171 | const option_list_t& extra_options, |
114 | BOOL layout_script_dialog) | 172 | BOOL layout_script_dialog) |
115 | : LLPanel("notify", LLRect(), BORDER_NO), | 173 | : LLPanel(xml_template->mLabel, LLRect(), BORDER_NO), |
116 | LLEventTimer(gSavedSettings.getF32("NotifyTipDuration")), | 174 | LLEventTimer(xml_template->mDuration), |
117 | mIsTip(FALSE), | 175 | mIsTip(FALSE), |
118 | mAnimating(TRUE), | 176 | mAnimating(TRUE), |
119 | mTimer(), | 177 | mUnique(xml_template->mUnique), |
120 | mNextBtn(NULL), | 178 | mNextBtn(NULL), |
121 | mCallback(callback), | 179 | mBehavior(new LLNotifyBehavior(callback, user_data)), |
122 | mData(user_data), | ||
123 | mNumOptions(0), | 180 | mNumOptions(0), |
124 | mDefaultOption(0) | 181 | mDefaultOption(0) |
125 | { | 182 | { |
@@ -133,31 +190,17 @@ LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t& | |||
133 | sFontSmall = LLFontGL::sSansSerifSmall; | 190 | sFontSmall = LLFontGL::sSansSerifSmall; |
134 | } | 191 | } |
135 | 192 | ||
136 | // get template | 193 | // setup paramaters |
137 | |||
138 | if (!sDefaultTemplate) | ||
139 | { | ||
140 | sDefaultTemplate = new LLNotifyBoxTemplate; | ||
141 | } | ||
142 | 194 | ||
143 | LLPointer<LLNotifyBoxTemplate> xml_template; | 195 | mMessage = xml_template->mMessage; |
144 | template_map_t::iterator iter = sNotifyTemplates.find(xml_desc); | 196 | LLAlertDialog::format(mMessage, args); |
145 | if (iter != sNotifyTemplates.end()) | 197 | |
146 | { | 198 | // use name + formatted text as unique key |
147 | xml_template = iter->second; | 199 | if (mUnique) |
148 | } | ||
149 | else | ||
150 | { | 200 | { |
151 | LLString tmsg = "[Notification template not found:\n " + xml_desc + " ]"; | 201 | sOpenUniqueNotifyBoxes[xml_template->mLabel + mMessage] = this; |
152 | sDefaultTemplate->setMessage(tmsg); | ||
153 | xml_template = sDefaultTemplate; | ||
154 | } | 202 | } |
155 | 203 | ||
156 | // setup paramaters | ||
157 | |||
158 | LLString message = xml_template->mMessage; | ||
159 | LLAlertDialog::format(message, args); | ||
160 | |||
161 | option_list_t options = xml_template->mOptions; | 204 | option_list_t options = xml_template->mOptions; |
162 | options.insert(options.end(), extra_options.begin(), extra_options.end()); | 205 | options.insert(options.end(), extra_options.begin(), extra_options.end()); |
163 | 206 | ||
@@ -175,13 +218,16 @@ LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t& | |||
175 | // account for the special layout of a tip notification) | 218 | // account for the special layout of a tip notification) |
176 | mIsCaution = ((xml_template->mIsCaution | is_caution) && (!mIsTip)); | 219 | mIsCaution = ((xml_template->mIsCaution | is_caution) && (!mIsTip)); |
177 | 220 | ||
178 | mAnimating = TRUE; | 221 | // Don't animate if behind other windows |
179 | mCallback = callback; | 222 | if( gNotifyBoxView->getChildCount() > 0 ) |
180 | mData = user_data; | 223 | mAnimating = FALSE; |
224 | else | ||
225 | mAnimating = TRUE; | ||
226 | |||
181 | mNumOptions = options.size(); | 227 | mNumOptions = options.size(); |
182 | mDefaultOption = xml_template->mDefaultOption; | 228 | mDefaultOption = xml_template->mDefaultOption; |
183 | 229 | ||
184 | LLRect rect = mIsTip ? getNotifyTipRect(message) | 230 | LLRect rect = mIsTip ? getNotifyTipRect(mMessage) |
185 | : getNotifyRect(mNumOptions, layout_script_dialog, mIsCaution); | 231 | : getNotifyRect(mNumOptions, layout_script_dialog, mIsCaution); |
186 | setRect(rect); | 232 | setRect(rect); |
187 | setFollows(mIsTip ? (FOLLOWS_BOTTOM|FOLLOWS_RIGHT) : (FOLLOWS_TOP|FOLLOWS_RIGHT)); | 233 | setFollows(mIsTip ? (FOLLOWS_BOTTOM|FOLLOWS_RIGHT) : (FOLLOWS_TOP|FOLLOWS_RIGHT)); |
@@ -255,7 +301,7 @@ LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t& | |||
255 | text = new LLTextEditor("box", | 301 | text = new LLTextEditor("box", |
256 | LLRect(x, y, mRect.getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16), | 302 | LLRect(x, y, mRect.getWidth()-2, mIsTip ? BOTTOM : BTN_TOP+16), |
257 | MAX_LENGTH, | 303 | MAX_LENGTH, |
258 | message, | 304 | mMessage, |
259 | sFont, | 305 | sFont, |
260 | FALSE); | 306 | FALSE); |
261 | text->setWordWrap(TRUE); | 307 | text->setWordWrap(TRUE); |
@@ -275,15 +321,15 @@ LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t& | |||
275 | if (mIsTip) | 321 | if (mIsTip) |
276 | { | 322 | { |
277 | // TODO: Make a separate archive for these. | 323 | // TODO: Make a separate archive for these. |
278 | LLChat chat(message); | 324 | LLChat chat(mMessage); |
279 | chat.mSourceType = CHAT_SOURCE_SYSTEM; | 325 | chat.mSourceType = CHAT_SOURCE_SYSTEM; |
280 | gFloaterChat->addChatHistory(chat); | 326 | LLFloaterChat::getInstance(LLSD())->addChatHistory(chat); |
281 | } | 327 | } |
282 | else | 328 | else |
283 | { | 329 | { |
284 | LLButton* btn; | 330 | LLButton* btn; |
285 | btn = new LLButton("next", | 331 | btn = new LLButton("next", |
286 | LLRect(mRect.getWidth()-24, BOTTOM_PAD+16, mRect.getWidth()-8, BOTTOM_PAD), | 332 | LLRect(mRect.getWidth()-18, BOTTOM_PAD+16, mRect.getWidth()-2, BOTTOM_PAD+2), |
287 | "notify_next.tga", | 333 | "notify_next.tga", |
288 | "notify_next.tga", | 334 | "notify_next.tga", |
289 | "", | 335 | "", |
@@ -328,7 +374,7 @@ LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t& | |||
328 | userdata->mSelf = this; | 374 | userdata->mSelf = this; |
329 | userdata->mButton = i; | 375 | userdata->mButton = i; |
330 | 376 | ||
331 | mBtnCallbackData.put(userdata); | 377 | mBtnCallbackData.push_back(userdata); |
332 | 378 | ||
333 | btn = new LLButton(options[i], btn_rect, "", onClickButton, userdata); | 379 | btn = new LLButton(options[i], btn_rect, "", onClickButton, userdata); |
334 | btn->setFont(font); | 380 | btn->setFont(font); |
@@ -361,10 +407,14 @@ LLNotifyBox::LLNotifyBox(const LLString& xml_desc, const LLString::format_map_t& | |||
361 | // virtual | 407 | // virtual |
362 | LLNotifyBox::~LLNotifyBox() | 408 | LLNotifyBox::~LLNotifyBox() |
363 | { | 409 | { |
364 | S32 count = mBtnCallbackData.count(); | 410 | delete mBehavior; |
365 | for (S32 i = 0; i < count; i++) | 411 | mBehavior = NULL; |
412 | |||
413 | std::for_each(mBtnCallbackData.begin(), mBtnCallbackData.end(), DeletePointer()); | ||
414 | |||
415 | if (mUnique) | ||
366 | { | 416 | { |
367 | delete mBtnCallbackData[i]; | 417 | sOpenUniqueNotifyBoxes.erase(mName + mMessage); |
368 | } | 418 | } |
369 | } | 419 | } |
370 | 420 | ||
@@ -398,7 +448,7 @@ BOOL LLNotifyBox::handleRightMouseDown(S32 x, S32 y, MASK mask) | |||
398 | // virtual | 448 | // virtual |
399 | void LLNotifyBox::draw() | 449 | void LLNotifyBox::draw() |
400 | { | 450 | { |
401 | F32 display_time = mTimer.getElapsedTimeF32(); | 451 | F32 display_time = mAnimateTimer.getElapsedTimeF32(); |
402 | 452 | ||
403 | if (mAnimating && display_time < ANIMATION_TIME) | 453 | if (mAnimating && display_time < ANIMATION_TIME) |
404 | { | 454 | { |
@@ -492,7 +542,10 @@ void LLNotifyBox::close() | |||
492 | gNotifyBoxView->showOnly(front); | 542 | gNotifyBoxView->showOnly(front); |
493 | // we're assuming that close is only called by user action (for non-tips), | 543 | // we're assuming that close is only called by user action (for non-tips), |
494 | // so we then give focus to the next close button | 544 | // so we then give focus to the next close button |
495 | front->mDefaultBtn->setFocus(TRUE); | 545 | if (front->mDefaultBtn) |
546 | { | ||
547 | front->mDefaultBtn->setFocus(TRUE); | ||
548 | } | ||
496 | gFocusMgr.triggerFocusFlash(); // TODO it's ugly to call this here | 549 | gFocusMgr.triggerFocusFlash(); // TODO it's ugly to call this here |
497 | } | 550 | } |
498 | } | 551 | } |
@@ -681,9 +734,9 @@ void LLNotifyBox::onClickButton(void* data) | |||
681 | return; | 734 | return; |
682 | } | 735 | } |
683 | 736 | ||
684 | if (self->mCallback) | 737 | if (self->mBehavior->mCallback) |
685 | { | 738 | { |
686 | self->mCallback(button, self->mData); | 739 | self->mBehavior->mCallback(button, self->mBehavior->mData); |
687 | } | 740 | } |
688 | 741 | ||
689 | self->close(); | 742 | self->close(); |
@@ -697,10 +750,54 @@ void LLNotifyBox::onClickNext(void* data) | |||
697 | self->moveToBack(); | 750 | self->moveToBack(); |
698 | } | 751 | } |
699 | 752 | ||
753 | // static | ||
754 | LLPointer<LLNotifyBoxTemplate> LLNotifyBox::getTemplate(const LLString& xml_desc) | ||
755 | { | ||
756 | // get template | ||
757 | |||
758 | if (!sDefaultTemplate) | ||
759 | { | ||
760 | // default template is non-unique, of course | ||
761 | sDefaultTemplate = new LLNotifyBoxTemplate(FALSE, gSavedSettings.getF32("NotifyTipDuration")); | ||
762 | sDefaultTemplate->addOption("OK", FALSE); | ||
763 | } | ||
764 | |||
765 | LLPointer<LLNotifyBoxTemplate> xml_template; | ||
766 | template_map_t::iterator iter = sNotifyTemplates.find(xml_desc); | ||
767 | if (iter != sNotifyTemplates.end()) | ||
768 | { | ||
769 | xml_template = iter->second; | ||
770 | } | ||
771 | else | ||
772 | { | ||
773 | LLString tmsg = "[Notification template not found:\n " + xml_desc + " ]"; | ||
774 | sDefaultTemplate->setMessage(tmsg); | ||
775 | xml_template = sDefaultTemplate; | ||
776 | } | ||
777 | |||
778 | return xml_template; | ||
779 | } | ||
780 | |||
700 | //----------------------------------------------------------------------------- | 781 | //----------------------------------------------------------------------------- |
701 | 782 | ||
702 | //static | 783 | //static |
703 | const LLString& LLNotifyBox::getTemplateMessage(const LLString& xml_desc) | 784 | const LLString LLNotifyBox::getTemplateMessage(const LLString& xml_desc, const LLString::format_map_t& args) |
785 | { | ||
786 | template_map_t::iterator iter = sNotifyTemplates.find(xml_desc); | ||
787 | if (iter != sNotifyTemplates.end()) | ||
788 | { | ||
789 | LLString message = iter->second->mMessage; | ||
790 | LLAlertDialog::format(message, args); | ||
791 | return message; | ||
792 | } | ||
793 | else | ||
794 | { | ||
795 | return xml_desc; | ||
796 | } | ||
797 | } | ||
798 | |||
799 | //static | ||
800 | const LLString LLNotifyBox::getTemplateMessage(const LLString& xml_desc) | ||
704 | { | 801 | { |
705 | template_map_t::iterator iter = sNotifyTemplates.find(xml_desc); | 802 | template_map_t::iterator iter = sNotifyTemplates.find(xml_desc); |
706 | if (iter != sNotifyTemplates.end()) | 803 | if (iter != sNotifyTemplates.end()) |
@@ -747,8 +844,14 @@ bool LLNotifyBox::parseNotify(const LLString& xml_filename) | |||
747 | { | 844 | { |
748 | continue; | 845 | continue; |
749 | } | 846 | } |
847 | |||
848 | BOOL unique = FALSE; | ||
849 | notify->getAttributeBOOL("unique", unique); | ||
850 | |||
851 | F32 duration = gSavedSettings.getF32("NotifyTipDuration"); | ||
852 | notify->getAttributeF32("duration", duration); | ||
750 | 853 | ||
751 | LLPointer<LLNotifyBoxTemplate> xml_template = new LLNotifyBoxTemplate; | 854 | LLPointer<LLNotifyBoxTemplate> xml_template = new LLNotifyBoxTemplate(unique, duration); |
752 | 855 | ||
753 | // label= | 856 | // label= |
754 | LLString notify_name; | 857 | LLString notify_name; |