diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/llfloaterchatterbox.cpp | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/linden/indra/newview/llfloaterchatterbox.cpp b/linden/indra/newview/llfloaterchatterbox.cpp new file mode 100644 index 0000000..11d2ee6 --- /dev/null +++ b/linden/indra/newview/llfloaterchatterbox.cpp | |||
@@ -0,0 +1,342 @@ | |||
1 | /** | ||
2 | * @file llfloaterchatterbox.cpp | ||
3 | * @author Richard | ||
4 | * @date 2007-05-08 | ||
5 | * @brief Implementation of the chatterbox integrated conversation ui | ||
6 | * | ||
7 | * Copyright (c) 2007-2007, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at http://secondlife.com/developers/opensource/flossexception | ||
21 | * | ||
22 | * By copying, modifying or distributing this software, you acknowledge | ||
23 | * that you have read and understood your obligations described above, | ||
24 | * and agree to abide by those obligations. | ||
25 | * | ||
26 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
27 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
28 | * COMPLETENESS OR PERFORMANCE. | ||
29 | */ | ||
30 | |||
31 | |||
32 | #include "llviewerprecompiledheaders.h" | ||
33 | |||
34 | #include "llfloaterchatterbox.h" | ||
35 | #include "llvieweruictrlfactory.h" | ||
36 | #include "llfloaterchat.h" | ||
37 | #include "llfloaterfriends.h" | ||
38 | #include "llfloatergroups.h" | ||
39 | #include "llviewercontrol.h" | ||
40 | #include "llimview.h" | ||
41 | #include "llimpanel.h" | ||
42 | |||
43 | // | ||
44 | // LLFloaterMyFriends | ||
45 | // | ||
46 | |||
47 | LLFloaterMyFriends::LLFloaterMyFriends(const LLSD& seed) | ||
48 | { | ||
49 | mFactoryMap["friends_panel"] = LLCallbackMap(LLFloaterMyFriends::createFriendsPanel, NULL); | ||
50 | mFactoryMap["groups_panel"] = LLCallbackMap(LLFloaterMyFriends::createGroupsPanel, NULL); | ||
51 | // do not automatically open singleton floaters (as result of getInstance()) | ||
52 | BOOL no_open = FALSE; | ||
53 | gUICtrlFactory->buildFloater(this, "floater_my_friends.xml", &getFactoryMap(), no_open); | ||
54 | } | ||
55 | |||
56 | LLFloaterMyFriends::~LLFloaterMyFriends() | ||
57 | { | ||
58 | } | ||
59 | |||
60 | BOOL LLFloaterMyFriends::postBuild() | ||
61 | { | ||
62 | mTabs = LLUICtrlFactory::getTabContainerByName(this, "friends_and_groups"); | ||
63 | |||
64 | return TRUE; | ||
65 | } | ||
66 | |||
67 | |||
68 | void LLFloaterMyFriends::onClose(bool app_quitting) | ||
69 | { | ||
70 | setVisible(FALSE); | ||
71 | } | ||
72 | |||
73 | //static | ||
74 | LLFloaterMyFriends* LLFloaterMyFriends::showInstance(const LLSD& id) | ||
75 | { | ||
76 | LLFloaterMyFriends* floaterp = LLUIInstanceMgr<LLFloaterMyFriends>::showInstance(id); | ||
77 | // garbage values in id will be interpreted as 0, or the friends tab | ||
78 | floaterp->mTabs->selectTab(id); | ||
79 | |||
80 | return floaterp; | ||
81 | } | ||
82 | |||
83 | //static | ||
84 | void LLFloaterMyFriends::hideInstance(const LLSD& id) | ||
85 | { | ||
86 | if(instanceVisible(id)) | ||
87 | { | ||
88 | LLFloaterChatterBox::hideInstance(LLSD()); | ||
89 | } | ||
90 | } | ||
91 | |||
92 | // is the specified panel currently visible | ||
93 | //static | ||
94 | BOOL LLFloaterMyFriends::instanceVisible(const LLSD& id) | ||
95 | { | ||
96 | // if singleton not created yet, trivially return false | ||
97 | if (!findInstance(id)) return FALSE; | ||
98 | |||
99 | LLFloaterMyFriends* floaterp = getInstance(id); | ||
100 | return floaterp->isInVisibleChain() && floaterp->mTabs->getCurrentPanelIndex() == id.asInteger(); | ||
101 | } | ||
102 | |||
103 | //static | ||
104 | void* LLFloaterMyFriends::createFriendsPanel(void* data) | ||
105 | { | ||
106 | return new LLPanelFriends(); | ||
107 | } | ||
108 | |||
109 | //static | ||
110 | void* LLFloaterMyFriends::createGroupsPanel(void* data) | ||
111 | { | ||
112 | return new LLPanelGroups(); | ||
113 | } | ||
114 | |||
115 | // | ||
116 | // LLFloaterChatterBox | ||
117 | // | ||
118 | LLFloaterChatterBox::LLFloaterChatterBox(const LLSD& seed) : | ||
119 | mActiveVoiceFloater(NULL) | ||
120 | { | ||
121 | mAutoResize = FALSE; | ||
122 | |||
123 | gUICtrlFactory->buildFloater(this, "floater_chatterbox.xml", NULL, FALSE); | ||
124 | addFloater(LLFloaterMyFriends::getInstance(0), TRUE); | ||
125 | if (gSavedSettings.getBOOL("ChatHistoryTornOff")) | ||
126 | { | ||
127 | LLFloaterChat* floater_chat = LLFloaterChat::getInstance(LLSD()); | ||
128 | // add then remove to set up relationship for re-attach | ||
129 | addFloater(floater_chat, FALSE); | ||
130 | removeFloater(floater_chat); | ||
131 | // reparent to floater view | ||
132 | gFloaterView->addChild(floater_chat); | ||
133 | } | ||
134 | else | ||
135 | { | ||
136 | addFloater(LLFloaterChat::getInstance(LLSD()), FALSE); | ||
137 | } | ||
138 | mTabContainer->lockTabs(); | ||
139 | } | ||
140 | |||
141 | LLFloaterChatterBox::~LLFloaterChatterBox() | ||
142 | { | ||
143 | } | ||
144 | |||
145 | BOOL LLFloaterChatterBox::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) | ||
146 | { | ||
147 | if (getEnabled() | ||
148 | && mask == MASK_CONTROL) | ||
149 | { | ||
150 | if (key == 'W') | ||
151 | { | ||
152 | LLFloater* floater = getActiveFloater(); | ||
153 | // is user closeable and is system closeable | ||
154 | if (floater && floater->canClose()) | ||
155 | { | ||
156 | if (floater->isCloseable()) | ||
157 | { | ||
158 | floater->close(); | ||
159 | } | ||
160 | else | ||
161 | { | ||
162 | // close chatterbox window if frontmost tab is reserved, non-closeable tab | ||
163 | // such as contacts or near me | ||
164 | close(); | ||
165 | } | ||
166 | } | ||
167 | return TRUE; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | return LLMultiFloater::handleKeyHere(key, mask, called_from_parent); | ||
172 | } | ||
173 | |||
174 | void LLFloaterChatterBox::draw() | ||
175 | { | ||
176 | // clear new im notifications when chatterbox is visible | ||
177 | if (!isMinimized()) | ||
178 | { | ||
179 | gIMMgr->clearNewIMNotification(); | ||
180 | } | ||
181 | LLFloater* current_active_floater = getCurrentVoiceFloater(); | ||
182 | // set icon on tab for floater currently associated with active voice channel | ||
183 | if(mActiveVoiceFloater != current_active_floater) | ||
184 | { | ||
185 | // remove image from old floater's tab | ||
186 | if (mActiveVoiceFloater) | ||
187 | { | ||
188 | mTabContainer->setTabImage(mActiveVoiceFloater, ""); | ||
189 | } | ||
190 | } | ||
191 | |||
192 | // update image on current active tab | ||
193 | if (current_active_floater) | ||
194 | { | ||
195 | LLColor4 icon_color = LLColor4::white; | ||
196 | LLVoiceChannel* channelp = LLVoiceChannel::getCurrentVoiceChannel(); | ||
197 | if (channelp) | ||
198 | { | ||
199 | if (channelp->isActive()) | ||
200 | { | ||
201 | icon_color = LLColor4::green; | ||
202 | } | ||
203 | else if (channelp->getState() == LLVoiceChannel::STATE_ERROR) | ||
204 | { | ||
205 | icon_color = LLColor4::red; | ||
206 | } | ||
207 | else // active, but not connected | ||
208 | { | ||
209 | icon_color = LLColor4::yellow; | ||
210 | } | ||
211 | } | ||
212 | mTabContainer->setTabImage(current_active_floater, "active_voice_tab.tga", icon_color); | ||
213 | } | ||
214 | |||
215 | mActiveVoiceFloater = current_active_floater; | ||
216 | |||
217 | LLFloater::draw(); | ||
218 | } | ||
219 | |||
220 | void LLFloaterChatterBox::onOpen() | ||
221 | { | ||
222 | gSavedSettings.setBOOL("ShowCommunicate", TRUE); | ||
223 | } | ||
224 | |||
225 | void LLFloaterChatterBox::onClose(bool app_quitting) | ||
226 | { | ||
227 | setVisible(FALSE); | ||
228 | gSavedSettings.setBOOL("ShowCommunicate", FALSE); | ||
229 | } | ||
230 | |||
231 | void LLFloaterChatterBox::removeFloater(LLFloater* floaterp) | ||
232 | { | ||
233 | if (floaterp->getName() == "chat floater") | ||
234 | { | ||
235 | // only my friends floater now locked | ||
236 | mTabContainer->lockTabs(1); | ||
237 | gSavedSettings.setBOOL("ChatHistoryTornOff", TRUE); | ||
238 | floaterp->setCanClose(TRUE); | ||
239 | } | ||
240 | LLMultiFloater::removeFloater(floaterp); | ||
241 | } | ||
242 | |||
243 | void LLFloaterChatterBox::addFloater(LLFloater* floaterp, | ||
244 | BOOL select_added_floater, | ||
245 | LLTabContainerCommon::eInsertionPoint insertion_point) | ||
246 | { | ||
247 | // make sure my friends and chat history both locked when re-attaching chat history | ||
248 | if (floaterp->getName() == "chat floater") | ||
249 | { | ||
250 | // select my friends tab | ||
251 | mTabContainer->selectFirstTab(); | ||
252 | // add chat history to the right of the my friends tab | ||
253 | //*TODO: respect select_added_floater so that we don't leave first tab selected | ||
254 | LLMultiFloater::addFloater(floaterp, select_added_floater, LLTabContainer::RIGHT_OF_CURRENT); | ||
255 | // make sure first two tabs are now locked | ||
256 | mTabContainer->lockTabs(2); | ||
257 | gSavedSettings.setBOOL("ChatHistoryTornOff", FALSE); | ||
258 | floaterp->setCanClose(FALSE); | ||
259 | } | ||
260 | else | ||
261 | { | ||
262 | LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point); | ||
263 | } | ||
264 | |||
265 | // make sure active voice icon shows up for new tab | ||
266 | if (floaterp == mActiveVoiceFloater) | ||
267 | { | ||
268 | mTabContainer->setTabImage(floaterp, "active_voice_tab.tga"); | ||
269 | } | ||
270 | } | ||
271 | |||
272 | |||
273 | //static | ||
274 | LLFloaterChatterBox* LLFloaterChatterBox::showInstance(const LLSD& seed) | ||
275 | { | ||
276 | LLFloaterChatterBox* floater = LLUISingleton<LLFloaterChatterBox>::showInstance(seed); | ||
277 | |||
278 | // if TRUE, show tab for active voice channel, otherwise, just show last tab | ||
279 | if (seed.asBoolean()) | ||
280 | { | ||
281 | LLFloater* floater_to_show = getCurrentVoiceFloater(); | ||
282 | if (floater_to_show) | ||
283 | { | ||
284 | floater_to_show->open(); | ||
285 | } | ||
286 | else | ||
287 | { | ||
288 | // just open chatterbox if there is no active voice window | ||
289 | LLUISingleton<LLFloaterChatterBox>::getInstance(seed)->open(); | ||
290 | } | ||
291 | } | ||
292 | |||
293 | return floater; | ||
294 | } | ||
295 | |||
296 | //static | ||
297 | BOOL LLFloaterChatterBox::instanceVisible(const LLSD &seed) | ||
298 | { | ||
299 | if (seed.asBoolean()) | ||
300 | { | ||
301 | LLFloater* floater_to_show = getCurrentVoiceFloater(); | ||
302 | if (floater_to_show) | ||
303 | { | ||
304 | return floater_to_show->isInVisibleChain(); | ||
305 | } | ||
306 | } | ||
307 | |||
308 | return LLUISingleton<LLFloaterChatterBox>::instanceVisible(seed); | ||
309 | } | ||
310 | |||
311 | //static | ||
312 | LLFloater* LLFloaterChatterBox::getCurrentVoiceFloater() | ||
313 | { | ||
314 | if (!LLVoiceClient::voiceEnabled()) | ||
315 | { | ||
316 | return NULL; | ||
317 | } | ||
318 | if (LLVoiceChannelProximal::getInstance() == LLVoiceChannel::getCurrentVoiceChannel()) | ||
319 | { | ||
320 | // show near me tab if in proximal channel | ||
321 | return LLFloaterChat::getInstance(LLSD()); | ||
322 | } | ||
323 | else | ||
324 | { | ||
325 | LLFloaterChatterBox* floater = LLFloaterChatterBox::getInstance(LLSD()); | ||
326 | // iterator over all IM tabs (skip friends and near me) | ||
327 | for (S32 i = 0; i < floater->getFloaterCount(); i++) | ||
328 | { | ||
329 | LLPanel* panelp = floater->mTabContainer->getPanelByIndex(i); | ||
330 | if (panelp->getName() == "im_floater") | ||
331 | { | ||
332 | // only LLFloaterIMPanels are called "im_floater" | ||
333 | LLFloaterIMPanel* im_floaterp = (LLFloaterIMPanel*)panelp; | ||
334 | if (im_floaterp->getVoiceChannel() == LLVoiceChannel::getCurrentVoiceChannel()) | ||
335 | { | ||
336 | return im_floaterp; | ||
337 | } | ||
338 | } | ||
339 | } | ||
340 | } | ||
341 | return NULL; | ||
342 | } | ||