00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llfloateractivespeakers.h"
00035
00036 #include "llagent.h"
00037 #include "llvoavatar.h"
00038 #include "llfloateravatarinfo.h"
00039 #include "llvieweruictrlfactory.h"
00040 #include "llviewercontrol.h"
00041 #include "llscrolllistctrl.h"
00042 #include "llbutton.h"
00043 #include "lltextbox.h"
00044 #include "llmutelist.h"
00045 #include "llviewerobjectlist.h"
00046 #include "llimpanel.h"
00047 #include "llsdutil.h"
00048
00049 const F32 SPEAKER_TIMEOUT = 10.f;
00050 const LLColor4 INACTIVE_COLOR(0.3f, 0.3f, 0.3f, 0.5f);
00051 const LLColor4 ACTIVE_COLOR(0.5f, 0.5f, 0.5f, 1.f);
00052 const F32 TYPING_ANIMATION_FPS = 2.5f;
00053
00054 LLLocalSpeakerMgr* gLocalSpeakerMgr = NULL;
00055 LLActiveSpeakerMgr* gActiveChannelSpeakerMgr = NULL;
00056
00057 LLSpeaker::speaker_map_t LLSpeaker::sSpeakers;
00058
00059 LLSpeaker::LLSpeaker(const LLUUID& id, const LLString& name, const ESpeakerType type) :
00060 mStatus(LLSpeaker::STATUS_TEXT_ONLY),
00061 mLastSpokeTime(0.f),
00062 mSpeechVolume(0.f),
00063 mHasSpoken(FALSE),
00064 mDotColor(LLColor4::white),
00065 mID(id),
00066 mTyping(FALSE),
00067 mSortIndex(0),
00068 mType(type)
00069 {
00070 mHandle.init();
00071 sSpeakers.insert(std::make_pair(mHandle, this));
00072 if (name.empty() && type == SPEAKER_AGENT)
00073 {
00074 lookupName();
00075 }
00076 else
00077 {
00078 mDisplayName = name;
00079 }
00080 mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT);
00081 }
00082
00083 LLSpeaker::~LLSpeaker()
00084 {
00085 sSpeakers.erase(mHandle);
00086 }
00087
00088 void LLSpeaker::lookupName()
00089 {
00090 gCacheName->getName(mID, onAvatarNameLookup, new LLViewHandle(mHandle));
00091 }
00092
00093
00094 void LLSpeaker::onAvatarNameLookup(const LLUUID& id, const char* first, const char* last, BOOL is_group, void* user_data)
00095 {
00096 LLViewHandle speaker_handle = *(LLViewHandle*)user_data;
00097 delete (LLViewHandle*)user_data;
00098
00099 speaker_map_t::iterator found_it = sSpeakers.find(speaker_handle);
00100 if (found_it != sSpeakers.end())
00101 {
00102 LLSpeaker* speakerp = found_it->second;
00103 if (speakerp)
00104 {
00105 speakerp->mDisplayName = llformat("%s %s", first, last);
00106 }
00107 }
00108 }
00109
00110
00111
00112 struct LLSortRecentSpeakers
00113 {
00114 bool operator()(const LLPointer<LLSpeaker> lhs, const LLPointer<LLSpeaker> rhs) const;
00115 };
00116
00117 bool LLSortRecentSpeakers::operator()(const LLPointer<LLSpeaker> lhs, const LLPointer<LLSpeaker> rhs) const
00118 {
00119
00120 if (lhs->mStatus != rhs->mStatus)
00121 {
00122 return (lhs->mStatus < rhs->mStatus);
00123 }
00124
00125
00126 if(lhs->mLastSpokeTime != rhs->mLastSpokeTime)
00127 {
00128 return (lhs->mLastSpokeTime > rhs->mLastSpokeTime);
00129 }
00130
00131
00132 return( lhs->mDisplayName.compare(rhs->mDisplayName) < 0 );
00133 }
00134
00135 LLFloaterActiveSpeakers::LLFloaterActiveSpeakers(const LLSD& seed) : mPanel(NULL)
00136 {
00137 mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, NULL);
00138
00139 BOOL no_open = FALSE;
00140 gUICtrlFactory->buildFloater(this, "floater_active_speakers.xml", &getFactoryMap(), no_open);
00141
00142
00143 mPanel->refreshSpeakers();
00144 }
00145
00146 LLFloaterActiveSpeakers::~LLFloaterActiveSpeakers()
00147 {
00148 }
00149
00150 void LLFloaterActiveSpeakers::onClose(bool app_quitting)
00151 {
00152 setVisible(FALSE);
00153 }
00154
00155 void LLFloaterActiveSpeakers::draw()
00156 {
00157
00158 mPanel->refreshSpeakers();
00159 LLFloater::draw();
00160 }
00161
00162 BOOL LLFloaterActiveSpeakers::postBuild()
00163 {
00164 mPanel = (LLPanelActiveSpeakers*)LLUICtrlFactory::getPanelByName(this, "active_speakers_panel");
00165 return TRUE;
00166 }
00167
00168 void LLFloaterActiveSpeakers::onChange()
00169 {
00170
00171 }
00172
00173
00174 void* LLFloaterActiveSpeakers::createSpeakersPanel(void* data)
00175 {
00176
00177 return new LLPanelActiveSpeakers(gActiveChannelSpeakerMgr, FALSE);
00178 }
00179
00180
00181
00182
00183
00184 LLPanelActiveSpeakers::LLPanelActiveSpeakers(LLSpeakerMgr* data_source, BOOL show_text_chatters) :
00185 mSpeakerList(NULL),
00186 mMuteVoiceCtrl(NULL),
00187 mMuteTextCtrl(NULL),
00188 mNameText(NULL),
00189 mProfileBtn(NULL),
00190 mShowTextChatters(show_text_chatters),
00191 mSpeakerMgr(data_source)
00192 {
00193 setMouseOpaque(FALSE);
00194 }
00195
00196 LLPanelActiveSpeakers::~LLPanelActiveSpeakers()
00197 {
00198
00199 }
00200
00201 BOOL LLPanelActiveSpeakers::postBuild()
00202 {
00203 mSpeakerList = LLUICtrlFactory::getScrollListByName(this, "speakers_list");
00204
00205 mMuteTextCtrl = (LLUICtrl*)getCtrlByNameAndType("mute_text_btn", WIDGET_TYPE_DONTCARE);
00206 childSetCommitCallback("mute_text_btn", onClickMuteTextCommit, this);
00207
00208 mMuteVoiceCtrl = (LLUICtrl*)getCtrlByNameAndType("mute_btn", WIDGET_TYPE_DONTCARE);
00209 childSetCommitCallback("mute_btn", onClickMuteVoiceCommit, this);
00210 childSetAction("mute_btn", onClickMuteVoice, this);
00211
00212 childSetCommitCallback("speaker_volume", onVolumeChange, this);
00213
00214 mNameText = LLUICtrlFactory::getTextBoxByName(this, "resident_name");
00215
00216 mProfileBtn = LLUICtrlFactory::getButtonByName(this, "profile_btn");
00217 childSetAction("profile_btn", onClickProfile, this);
00218 return TRUE;
00219 }
00220
00221 void LLPanelActiveSpeakers::refreshSpeakers()
00222 {
00223
00224 LLUUID selected_id = mSpeakerList->getSimpleSelectedValue().asUUID();
00225 S32 scroll_pos = mSpeakerList->getScrollInterface()->getScrollPos();
00226
00227 BOOL sort_ascending = mSpeakerList->getSortAscending();
00228 LLString sort_column = mSpeakerList->getSortColumnName();
00229
00230
00231 if (sort_column.empty())
00232 {
00233 sort_column = "speaking_status";
00234 }
00235
00236 mSpeakerMgr->update();
00237
00238
00239 mSpeakerList->clearRows();
00240
00241 LLSpeakerMgr::speaker_list_t speaker_list;
00242 mSpeakerMgr->getSpeakerList(&speaker_list, mShowTextChatters);
00243 for (LLSpeakerMgr::speaker_list_t::const_iterator speaker_it = speaker_list.begin(); speaker_it != speaker_list.end(); ++speaker_it)
00244 {
00245 LLUUID speaker_id = (*speaker_it)->mID;
00246 LLPointer<LLSpeaker> speakerp = (*speaker_it);
00247
00248
00249 LLString speaking_order_sort_string = llformat("%010d", speakerp->mSortIndex);
00250
00251 LLSD row;
00252 row["id"] = speaker_id;
00253
00254 row["columns"][0]["column"] = "icon_speaking_status";
00255 row["columns"][0]["type"] = "icon";
00256 row["columns"][0]["color"] = speakerp->mDotColor.getValue();
00257 LLString icon_image_id;
00258
00259 S32 icon_image_idx = llmin(2, llfloor((speakerp->mSpeechVolume / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 3.f));
00260 switch(icon_image_idx)
00261 {
00262 case 0:
00263 icon_image_id = gViewerArt.getString("icn_active-speakers-dot-lvl0.tga");
00264 break;
00265 case 1:
00266 icon_image_id = gViewerArt.getString("icn_active-speakers-dot-lvl1.tga");
00267 break;
00268 case 2:
00269 icon_image_id = gViewerArt.getString("icn_active-speakers-dot-lvl2.tga");
00270 break;
00271 }
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 row["columns"][0]["value"] = (speakerp->mStatus == LLSpeaker::STATUS_MUTED) ?
00292 gViewerArt.getString("mute_icon.tga") : icon_image_id;
00293 if (speakerp->mStatus > LLSpeaker::STATUS_VOICE_ACTIVE && speakerp->mStatus != LLSpeaker::STATUS_MUTED)
00294 {
00295
00296 row["columns"][0]["color"] = LLColor4(0.f, 0.f, 0.f, 0.f).getValue();
00297 }
00298 row["columns"][1]["column"] = "speaker_name";
00299 row["columns"][1]["type"] = "text";
00300 if (speakerp->mStatus == LLSpeaker::STATUS_NOT_IN_CHANNEL)
00301 {
00302
00303 row["columns"][1]["color"] = LLColor4::grey4.getValue();
00304 }
00305
00306 if (speakerp->mDisplayName.empty())
00307 {
00308 row["columns"][1]["value"] = LLCacheName::getDefaultName();
00309 }
00310 else
00311 {
00312 row["columns"][1]["value"] = speakerp->mDisplayName;
00313 }
00314
00315 row["columns"][2]["column"] = "speaking_status";
00316 row["columns"][2]["type"] = "text";
00317
00318
00319 row["columns"][2]["value"] = speaking_order_sort_string;
00320
00321 mSpeakerList->addElement(row);
00322 }
00323
00324
00325 mSpeakerList->sortByColumn(sort_column, sort_ascending);
00326
00327 if (selected_id.isNull())
00328 {
00329 mSpeakerList->selectFirstItem();
00330 }
00331 else
00332 {
00333 mSpeakerList->selectByValue(selected_id);
00334 }
00335
00336 LLPointer<LLSpeaker> speakerp = mSpeakerMgr->findSpeaker(selected_id);
00337
00338 if (gMuteListp)
00339 {
00340
00341 if (mMuteVoiceCtrl)
00342 {
00343 mMuteVoiceCtrl->setValue(gMuteListp->isMuted(selected_id, LLMute::flagVoiceChat));
00344 mMuteVoiceCtrl->setEnabled(selected_id.notNull()
00345 && selected_id != gAgent.getID()
00346 && (speakerp.notNull() && speakerp->mType == LLSpeaker::SPEAKER_AGENT));
00347 }
00348 if (mMuteTextCtrl)
00349 {
00350 mMuteTextCtrl->setValue(gMuteListp->isMuted(selected_id, LLMute::flagTextChat));
00351 mMuteTextCtrl->setEnabled(selected_id.notNull() && selected_id != gAgent.getID() && speakerp.notNull() && !gMuteListp->isLinden(speakerp->mDisplayName));
00352 }
00353 childSetValue("speaker_volume", gVoiceClient->getUserVolume(selected_id));
00354 childSetEnabled("speaker_volume", selected_id.notNull()
00355 && selected_id != gAgent.getID()
00356 && (speakerp.notNull() && speakerp->mType == LLSpeaker::SPEAKER_AGENT));
00357 if (mProfileBtn)
00358 {
00359 mProfileBtn->setEnabled(selected_id.notNull());
00360 }
00361 }
00362
00363
00364 if (mNameText)
00365 {
00366 if (speakerp)
00367 {
00368 mNameText->setValue(speakerp->mDisplayName);
00369 }
00370 else
00371 {
00372 mNameText->setValue(LLString::null);
00373 }
00374 }
00375
00376
00377 mSpeakerList->getScrollInterface()->setScrollPos(scroll_pos);
00378 }
00379
00380 void LLPanelActiveSpeakers::setSpeaker(const LLUUID& id, const LLString& name, LLSpeaker::ESpeakerStatus status, LLSpeaker::ESpeakerType type)
00381 {
00382 mSpeakerMgr->setSpeaker(id, name, status, type);
00383 }
00384
00385
00386
00387 void LLPanelActiveSpeakers::onClickMuteTextCommit(LLUICtrl* ctrl, void* user_data)
00388 {
00389 LLPanelActiveSpeakers* panelp = (LLPanelActiveSpeakers*)user_data;
00390 LLUUID speaker_id = panelp->mSpeakerList->getValue().asUUID();
00391 BOOL is_muted = gMuteListp->isMuted(speaker_id, LLMute::flagTextChat);
00392 std::string name;
00393
00394
00395 LLPointer<LLSpeaker> speakerp = panelp->mSpeakerMgr->findSpeaker(speaker_id);
00396 if (speakerp.isNull())
00397 {
00398 return;
00399 }
00400
00401 name = speakerp->mDisplayName;
00402
00403 LLMute mute(speaker_id, name, speakerp->mType == LLSpeaker::SPEAKER_AGENT ? LLMute::AGENT : LLMute::OBJECT);
00404
00405 if (!is_muted)
00406 {
00407 gMuteListp->add(mute, LLMute::flagTextChat);
00408 }
00409 else
00410 {
00411 gMuteListp->remove(mute, LLMute::flagTextChat);
00412 }
00413 }
00414
00415
00416 void LLPanelActiveSpeakers::onClickMuteVoice(void* user_data)
00417 {
00418 onClickMuteVoiceCommit(NULL, user_data);
00419 }
00420
00421
00422 void LLPanelActiveSpeakers::onClickMuteVoiceCommit(LLUICtrl* ctrl, void* user_data)
00423 {
00424 LLPanelActiveSpeakers* panelp = (LLPanelActiveSpeakers*)user_data;
00425 LLUUID speaker_id = panelp->mSpeakerList->getValue().asUUID();
00426 BOOL is_muted = gMuteListp->isMuted(speaker_id, LLMute::flagVoiceChat);
00427 std::string name;
00428
00429 LLPointer<LLSpeaker> speakerp = panelp->mSpeakerMgr->findSpeaker(speaker_id);
00430 if (speakerp.isNull())
00431 {
00432 return;
00433 }
00434
00435 name = speakerp->mDisplayName;
00436
00437
00438 LLMute mute(speaker_id, name, LLMute::AGENT);
00439
00440 if (!is_muted)
00441 {
00442 gMuteListp->add(mute, LLMute::flagVoiceChat);
00443 }
00444 else
00445 {
00446 gMuteListp->remove(mute, LLMute::flagVoiceChat);
00447 }
00448 }
00449
00450
00451
00452 void LLPanelActiveSpeakers::onVolumeChange(LLUICtrl* source, void* user_data)
00453 {
00454 LLPanelActiveSpeakers* panelp = (LLPanelActiveSpeakers*)user_data;
00455 LLUUID speaker_id = panelp->mSpeakerList->getValue().asUUID();
00456
00457 gVoiceClient->setUserVolume(speaker_id, (F32)panelp->childGetValue("speaker_volume").asReal());
00458 }
00459
00460
00461 void LLPanelActiveSpeakers::onClickProfile(void* user_data)
00462 {
00463 LLPanelActiveSpeakers* panelp = (LLPanelActiveSpeakers*)user_data;
00464 LLUUID speaker_id = panelp->mSpeakerList->getValue().asUUID();
00465
00466 LLFloaterAvatarInfo::showFromDirectory(speaker_id);
00467 }
00468
00469
00470
00471
00472
00473 LLSpeakerMgr::LLSpeakerMgr(LLVoiceChannel* channelp) :
00474 mVoiceChannel(channelp)
00475 {
00476 }
00477
00478 LLSpeakerMgr::~LLSpeakerMgr()
00479 {
00480 }
00481
00482 LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const LLString& name, LLSpeaker::ESpeakerStatus status, LLSpeaker::ESpeakerType type)
00483 {
00484 if (id.isNull()) return NULL;
00485
00486 LLPointer<LLSpeaker> speakerp;
00487 if (mSpeakers.find(id) == mSpeakers.end())
00488 {
00489 speakerp = new LLSpeaker(id, name, type);
00490 speakerp->mStatus = status;
00491 mSpeakers.insert(std::make_pair(speakerp->mID, speakerp));
00492 mSpeakersSorted.push_back(speakerp);
00493 }
00494 else
00495 {
00496 speakerp = findSpeaker(id);
00497 if (speakerp.notNull())
00498 {
00499
00500 speakerp->mStatus = llmin(speakerp->mStatus, status);
00501 speakerp->mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT);
00502
00503
00504
00505 if (type == LLSpeaker::SPEAKER_AGENT)
00506 {
00507 speakerp->mType = LLSpeaker::SPEAKER_AGENT;
00508 speakerp->lookupName();
00509 }
00510 }
00511 }
00512
00513 return speakerp;
00514 }
00515
00516 void LLSpeakerMgr::update()
00517 {
00518 if (!gVoiceClient)
00519 {
00520 return;
00521 }
00522
00523 LLColor4 speaking_color = gSavedSettings.getColor4("SpeakingColor");
00524 LLColor4 overdriven_color = gSavedSettings.getColor4("OverdrivenColor");
00525
00526 updateSpeakerList();
00527
00528
00529 BOOL voice_channel_active = (!mVoiceChannel && gVoiceClient->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive());
00530 for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end();)
00531 {
00532 LLUUID speaker_id = speaker_it->first;
00533 LLSpeaker* speakerp = speaker_it->second;
00534
00535 speaker_map_t::iterator cur_speaker_it = speaker_it++;
00536
00537 if (voice_channel_active && gVoiceClient->getVoiceEnabled(speaker_id))
00538 {
00539 speakerp->mSpeechVolume = gVoiceClient->getCurrentPower(speaker_id);
00540
00541 if (gVoiceClient->getOnMuteList(speaker_id))
00542 {
00543 speakerp->mStatus = LLSpeaker::STATUS_MUTED;
00544 speakerp->mDotColor = LLColor4::white;
00545 }
00546 else if (gVoiceClient->getIsSpeaking(speaker_id))
00547 {
00548
00549 if (speakerp->mStatus != LLSpeaker::STATUS_SPEAKING)
00550 {
00551 speakerp->mLastSpokeTime = mSpeechTimer.getElapsedTimeF32();
00552 speakerp->mHasSpoken = TRUE;
00553 }
00554 speakerp->mStatus = LLSpeaker::STATUS_SPEAKING;
00555
00556 speakerp->mDotColor = speaking_color;
00557 if (speakerp->mSpeechVolume > LLVoiceClient::OVERDRIVEN_POWER_LEVEL)
00558 {
00559 speakerp->mDotColor = overdriven_color;
00560 }
00561 }
00562 else
00563 {
00564 speakerp->mSpeechVolume = 0.f;
00565 speakerp->mDotColor = ACTIVE_COLOR;
00566
00567 if (speakerp->mHasSpoken)
00568 {
00569
00570 speakerp->mStatus = LLSpeaker::STATUS_HAS_SPOKEN;
00571 }
00572 else
00573 {
00574
00575 speakerp->mStatus = LLSpeaker::STATUS_VOICE_ACTIVE;
00576 }
00577 }
00578 }
00579
00580 else if (speakerp->mStatus != LLSpeaker::STATUS_NOT_IN_CHANNEL)
00581 {
00582 speakerp->mStatus = LLSpeaker::STATUS_TEXT_ONLY;
00583 speakerp->mSpeechVolume = 0.f;
00584 speakerp->mDotColor = ACTIVE_COLOR;
00585 }
00586 }
00587
00588
00589 std::sort(mSpeakersSorted.begin(), mSpeakersSorted.end(), LLSortRecentSpeakers());
00590
00591
00592
00593
00594 S32 recent_speaker_count = 0;
00595 S32 sort_index = 0;
00596 speaker_list_t::iterator sorted_speaker_it;
00597 for(sorted_speaker_it = mSpeakersSorted.begin();
00598 sorted_speaker_it != mSpeakersSorted.end(); )
00599 {
00600 LLPointer<LLSpeaker> speakerp = *sorted_speaker_it;
00601
00602
00603 if (speakerp->mStatus == LLSpeaker::STATUS_HAS_SPOKEN)
00604 {
00605 speakerp->mDotColor = lerp(speaking_color, ACTIVE_COLOR, clamp_rescale((F32)recent_speaker_count, -2.f, 3.f, 0.f, 1.f));
00606 recent_speaker_count++;
00607 }
00608
00609
00610 speakerp->mSortIndex = sort_index++;
00611
00612
00613 if (speakerp->mStatus == LLSpeaker::STATUS_NOT_IN_CHANNEL && speakerp->mActivityTimer.hasExpired())
00614 {
00615 mSpeakers.erase(speakerp->mID);
00616 sorted_speaker_it = mSpeakersSorted.erase(sorted_speaker_it);
00617 }
00618 else
00619 {
00620 ++sorted_speaker_it;
00621 }
00622 }
00623 }
00624
00625 void LLSpeakerMgr::updateSpeakerList()
00626 {
00627
00628 if ((!mVoiceChannel && gVoiceClient->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive()))
00629 {
00630 LLVoiceClient::participantMap* participants = gVoiceClient->getParticipantList();
00631 LLVoiceClient::participantMap::iterator participant_it;
00632
00633
00634 for (participant_it = participants->begin(); participant_it != participants->end(); ++participant_it)
00635 {
00636 LLVoiceClient::participantState* participantp = participant_it->second;
00637 setSpeaker(participantp->mAvatarID, "", LLSpeaker::STATUS_VOICE_ACTIVE);
00638 }
00639 }
00640 }
00641
00642 const LLPointer<LLSpeaker> LLSpeakerMgr::findSpeaker(const LLUUID& speaker_id)
00643 {
00644 speaker_map_t::iterator found_it = mSpeakers.find(speaker_id);
00645 if (found_it == mSpeakers.end())
00646 {
00647 return NULL;
00648 }
00649 return found_it->second;
00650 }
00651
00652 void LLSpeakerMgr::getSpeakerList(speaker_list_t* speaker_list, BOOL include_text)
00653 {
00654 speaker_list->clear();
00655 for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end(); ++speaker_it)
00656 {
00657 LLPointer<LLSpeaker> speakerp = speaker_it->second;
00658
00659 if (include_text || speakerp->mStatus != LLSpeaker::STATUS_TEXT_ONLY)
00660 {
00661 speaker_list->push_back(speakerp);
00662 }
00663 }
00664 }
00665
00666 void LLSpeakerMgr::setSpeakerTyping(const LLUUID& speaker_id, BOOL typing)
00667 {
00668 LLPointer<LLSpeaker> speakerp = findSpeaker(speaker_id);
00669 if (speakerp.notNull())
00670 {
00671 speakerp->mTyping = typing;
00672 }
00673 }
00674
00675
00676 void LLSpeakerMgr::speakerChatted(const LLUUID& speaker_id)
00677 {
00678 LLPointer<LLSpeaker> speakerp = findSpeaker(speaker_id);
00679 if (speakerp.notNull())
00680 {
00681 speakerp->mLastSpokeTime = mSpeechTimer.getElapsedTimeF32();
00682 speakerp->mHasSpoken = TRUE;
00683 }
00684 }
00685
00686 BOOL LLSpeakerMgr::isVoiceActive()
00687 {
00688
00689 return LLVoiceClient::voiceEnabled() && mVoiceChannel && mVoiceChannel->isActive();
00690 }
00691
00692
00693
00694
00695
00696 LLIMSpeakerMgr::LLIMSpeakerMgr(LLVoiceChannel* channel) : LLSpeakerMgr(channel)
00697 {
00698 }
00699
00700 void LLIMSpeakerMgr::updateSpeakerList()
00701 {
00702
00703
00704 return;
00705 }
00706
00707 void LLIMSpeakerMgr::processSpeakerList(LLSD list)
00708 {
00709 for(LLSD::array_iterator list_it = list.beginArray();
00710 list_it != list.endArray();
00711 ++list_it)
00712 {
00713 LLUUID agent_id(list_it->asUUID());
00714
00715 setSpeaker(agent_id, "", LLSpeaker::STATUS_TEXT_ONLY);
00716 }
00717 }
00718
00719 void LLIMSpeakerMgr::processSpeakerMap(LLSD map)
00720 {
00721 for(LLSD::map_iterator map_it = map.beginMap();
00722 map_it != map.endMap();
00723 ++map_it)
00724 {
00725
00726 setSpeaker(LLUUID(map_it->first));
00727 }
00728 }
00729
00730
00731
00732 void LLIMSpeakerMgr::processSpeakerListUpdate(LLSD update)
00733 {
00734 for(LLSD::map_iterator update_it = update.beginMap();
00735 update_it != update.endMap();
00736 ++update_it)
00737 {
00738 LLUUID agent_id(update_it->first);
00739
00740 if (update_it->second.asString() == "LEAVE")
00741 {
00742 LLPointer<LLSpeaker> speakerp = findSpeaker(agent_id);
00743 if (speakerp)
00744 {
00745 speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL;
00746 speakerp->mDotColor = INACTIVE_COLOR;
00747 speakerp->mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT);
00748 }
00749 }
00750 else if (update_it->second.asString() == "ENTER")
00751 {
00752
00753 setSpeaker(agent_id);
00754 }
00755 else
00756 {
00757 llwarns << "LLIMSpeakerMgr::processSpeakerListUpdate() : bad membership list update " << ll_print_sd(update_it->second) << llendl;
00758 }
00759 }
00760 }
00761
00762
00763
00764
00765
00766
00767 LLActiveSpeakerMgr::LLActiveSpeakerMgr() : LLSpeakerMgr(NULL)
00768 {
00769 }
00770
00771 void LLActiveSpeakerMgr::updateSpeakerList()
00772 {
00773
00774 mVoiceChannel = LLVoiceChannel::getCurrentVoiceChannel();
00775
00776
00777 if (LLVoiceChannel::getCurrentVoiceChannel() != mVoiceChannel)
00778 {
00779 mSpeakers.clear();
00780 mSpeakersSorted.clear();
00781 mVoiceChannel = LLVoiceChannel::getCurrentVoiceChannel();
00782 }
00783 LLSpeakerMgr::updateSpeakerList();
00784 }
00785
00786
00787
00788
00789
00790
00791
00792 LLLocalSpeakerMgr::LLLocalSpeakerMgr() : LLSpeakerMgr(LLVoiceChannelProximal::getInstance())
00793 {
00794 }
00795
00796 LLLocalSpeakerMgr::~LLLocalSpeakerMgr ()
00797 {
00798 }
00799
00800 void LLLocalSpeakerMgr::updateSpeakerList()
00801 {
00802
00803 LLSpeakerMgr::updateSpeakerList();
00804
00805
00806 std::vector< LLCharacter* >::iterator avatar_it;
00807 for(avatar_it = LLCharacter::sInstances.begin(); avatar_it != LLCharacter::sInstances.end(); ++avatar_it)
00808 {
00809 LLVOAvatar* avatarp = (LLVOAvatar*)*avatar_it;
00810 if (dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) <= CHAT_NORMAL_RADIUS)
00811 {
00812 setSpeaker(avatarp->getID());
00813 }
00814 }
00815
00816
00817 for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end(); ++speaker_it)
00818 {
00819 LLUUID speaker_id = speaker_it->first;
00820 LLSpeaker* speakerp = speaker_it->second;
00821 if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY)
00822 {
00823 LLVOAvatar* avatarp = (LLVOAvatar*)gObjectList.findObject(speaker_id);
00824 if (!avatarp || dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) > CHAT_NORMAL_RADIUS)
00825 {
00826 speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL;
00827 speakerp->mDotColor = INACTIVE_COLOR;
00828 speakerp->mActivityTimer.resetWithExpiry(SPEAKER_TIMEOUT);
00829 }
00830 }
00831 }
00832 }