[Voice Update] LLPanelActiveSpeakers to LLParticipantList
Minor updates to code, mostly just a migration with some v3 stuff commented, since we don't have LLAvatarList and must use buttons since scrolllist menus don't actually exist nicely yet. Added toggleMuteVoice and isVoiceMuted to LLAvatarActions Added a minor touch to the voice volume slider, it'll now offer changing your own volume while in an active voice session.. nice to not drop out of an import voice session just to fix yourself. Also, fix a bug with SpeakerMgr's not flagging speakers for removal properly, causing external speakers and speakers managed by LLActiveSpeakerMgr to never actually get removed.
This commit is contained in:
@@ -381,6 +381,7 @@ set(viewer_SOURCE_FILES
|
|||||||
llpanelvolume.cpp
|
llpanelvolume.cpp
|
||||||
llpanelweb.cpp
|
llpanelweb.cpp
|
||||||
llparcelselection.cpp
|
llparcelselection.cpp
|
||||||
|
llparticipantlist.cpp
|
||||||
llpatchvertexarray.cpp
|
llpatchvertexarray.cpp
|
||||||
llpathfindingcharacter.cpp
|
llpathfindingcharacter.cpp
|
||||||
llpathfindingcharacterlist.cpp
|
llpathfindingcharacterlist.cpp
|
||||||
@@ -884,6 +885,7 @@ set(viewer_HEADER_FILES
|
|||||||
llpanelvolume.h
|
llpanelvolume.h
|
||||||
llpanelweb.h
|
llpanelweb.h
|
||||||
llparcelselection.h
|
llparcelselection.h
|
||||||
|
llparticipantlist.h
|
||||||
llpatchvertexarray.h
|
llpatchvertexarray.h
|
||||||
llpathfindingcharacter.h
|
llpathfindingcharacter.h
|
||||||
llpathfindingcharacterlist.h
|
llpathfindingcharacterlist.h
|
||||||
|
|||||||
@@ -77,6 +77,7 @@
|
|||||||
#include "llviewerstats.h"
|
#include "llviewerstats.h"
|
||||||
#include "llviewerwindow.h"
|
#include "llviewerwindow.h"
|
||||||
#include "llvoavatarself.h"
|
#include "llvoavatarself.h"
|
||||||
|
#include "llvoiceclient.h"
|
||||||
#include "llworld.h"
|
#include "llworld.h"
|
||||||
#include "llworldmap.h"
|
#include "llworldmap.h"
|
||||||
#include "llworldmapmessage.h"
|
#include "llworldmapmessage.h"
|
||||||
@@ -85,11 +86,9 @@
|
|||||||
#include "llurldispatcher.h"
|
#include "llurldispatcher.h"
|
||||||
#include "llimview.h" //For gIMMgr
|
#include "llimview.h" //For gIMMgr
|
||||||
//Floaters
|
//Floaters
|
||||||
#include "llfloateractivespeakers.h"
|
|
||||||
#include "llfloateravatarinfo.h"
|
#include "llfloateravatarinfo.h"
|
||||||
#include "llfloaterchat.h"
|
#include "llfloaterchat.h"
|
||||||
#include "llfloaterdirectory.h"
|
#include "llfloaterdirectory.h"
|
||||||
#include "llfloatergroupinfo.h"
|
|
||||||
#include "llfloatergroups.h"
|
#include "llfloatergroups.h"
|
||||||
#include "llfloaterland.h"
|
#include "llfloaterland.h"
|
||||||
#include "llfloatermap.h"
|
#include "llfloatermap.h"
|
||||||
|
|||||||
@@ -510,6 +510,26 @@ void LLAvatarActions::toggleBlock(const LLUUID& id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void LLAvatarActions::toggleMuteVoice(const LLUUID& id)
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
gCacheName->getFullName(id, name); // needed for mute
|
||||||
|
|
||||||
|
LLMuteList* mute_list = LLMuteList::getInstance();
|
||||||
|
bool is_muted = mute_list->isMuted(id, LLMute::flagVoiceChat);
|
||||||
|
|
||||||
|
LLMute mute(id, name, LLMute::AGENT);
|
||||||
|
if (!is_muted)
|
||||||
|
{
|
||||||
|
mute_list->add(mute, LLMute::flagVoiceChat);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mute_list->remove(mute, LLMute::flagVoiceChat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool LLAvatarActions::canOfferTeleport(const LLUUID& id)
|
bool LLAvatarActions::canOfferTeleport(const LLUUID& id)
|
||||||
{
|
{
|
||||||
@@ -724,6 +744,12 @@ bool LLAvatarActions::isBlocked(const LLUUID& id)
|
|||||||
return LLMuteList::getInstance()->isMuted(id);
|
return LLMuteList::getInstance()->isMuted(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool LLAvatarActions::isVoiceMuted(const LLUUID& id)
|
||||||
|
{
|
||||||
|
return LLMuteList::getInstance()->isMuted(id, LLMute::flagVoiceChat);
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool LLAvatarActions::canBlock(const LLUUID& id)
|
bool LLAvatarActions::canBlock(const LLUUID& id)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -104,6 +104,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
static void toggleBlock(const LLUUID& id);
|
static void toggleBlock(const LLUUID& id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Block/unblock the avatar voice.
|
||||||
|
*/
|
||||||
|
static void toggleMuteVoice(const LLUUID& id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if avatar with "id" is a friend
|
* Return true if avatar with "id" is a friend
|
||||||
*/
|
*/
|
||||||
@@ -114,6 +119,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
static bool isBlocked(const LLUUID& id);
|
static bool isBlocked(const LLUUID& id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if the avatar voice is blocked
|
||||||
|
*/
|
||||||
|
static bool isVoiceMuted(const LLUUID& id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if you can block the avatar
|
* @return true if you can block the avatar
|
||||||
*/
|
*/
|
||||||
@@ -185,4 +195,3 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#endif // LL_LLAVATARACTIONS_H
|
#endif // LL_LLAVATARACTIONS_H
|
||||||
|
|
||||||
|
|||||||
@@ -33,30 +33,9 @@
|
|||||||
|
|
||||||
#include "llfloateractivespeakers.h"
|
#include "llfloateractivespeakers.h"
|
||||||
|
|
||||||
#include "llagent.h"
|
#include "llparticipantlist.h"
|
||||||
#include "llavataractions.h"
|
|
||||||
#include "llbutton.h"
|
|
||||||
#include "llmutelist.h"
|
|
||||||
#include "llscrolllistctrl.h"
|
|
||||||
#include "llspeakers.h"
|
#include "llspeakers.h"
|
||||||
#include "lltextbox.h"
|
|
||||||
#include "lluictrlfactory.h"
|
#include "lluictrlfactory.h"
|
||||||
#include "llviewerobjectlist.h"
|
|
||||||
#include "llviewerwindow.h"
|
|
||||||
#include "llvoavatar.h"
|
|
||||||
#include "llworld.h"
|
|
||||||
|
|
||||||
// [RLVa:KB]
|
|
||||||
#include "rlvhandler.h"
|
|
||||||
// [/RLVa:KB]
|
|
||||||
|
|
||||||
using namespace LLOldEvents;
|
|
||||||
|
|
||||||
const F32 RESORT_TIMEOUT = 5.f; // seconds of mouse inactivity before it's ok to sort regardless of mouse-in-view.
|
|
||||||
|
|
||||||
//
|
|
||||||
// LLFloaterActiveSpeakers
|
|
||||||
//
|
|
||||||
|
|
||||||
LLFloaterActiveSpeakers::LLFloaterActiveSpeakers(const LLSD& seed) : mPanel(NULL)
|
LLFloaterActiveSpeakers::LLFloaterActiveSpeakers(const LLSD& seed) : mPanel(NULL)
|
||||||
{
|
{
|
||||||
@@ -96,7 +75,7 @@ void LLFloaterActiveSpeakers::draw()
|
|||||||
|
|
||||||
BOOL LLFloaterActiveSpeakers::postBuild()
|
BOOL LLFloaterActiveSpeakers::postBuild()
|
||||||
{
|
{
|
||||||
mPanel = getChild<LLPanelActiveSpeakers>("active_speakers_panel");
|
mPanel = getChild<LLParticipantList>("active_speakers_panel");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,588 +87,6 @@ void LLFloaterActiveSpeakers::onParticipantsChanged()
|
|||||||
//static
|
//static
|
||||||
void* LLFloaterActiveSpeakers::createSpeakersPanel(void* data)
|
void* LLFloaterActiveSpeakers::createSpeakersPanel(void* data)
|
||||||
{
|
{
|
||||||
// don't show text only speakers
|
return new LLParticipantList(LLActiveSpeakerMgr::getInstance(), /*show_text_chatters=*/ false);
|
||||||
return new LLPanelActiveSpeakers(LLActiveSpeakerMgr::getInstance(), FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// LLPanelActiveSpeakers::SpeakerMuteListener
|
|
||||||
//
|
|
||||||
bool LLPanelActiveSpeakers::SpeakerMuteListener::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
|
||||||
{
|
|
||||||
LLPointer<LLSpeaker> speakerp = (LLSpeaker*)event->getSource();
|
|
||||||
if (speakerp.isNull()) return false;
|
|
||||||
|
|
||||||
// update UI on confirmation of moderator mutes
|
|
||||||
if (event->getValue().asString() == "voice")
|
|
||||||
{
|
|
||||||
mPanel->childSetValue("moderator_allow_voice", !speakerp->mModeratorMutedVoice);
|
|
||||||
}
|
|
||||||
if (event->getValue().asString() == "text")
|
|
||||||
{
|
|
||||||
mPanel->childSetValue("moderator_allow_text", !speakerp->mModeratorMutedText);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// LLPanelActiveSpeakers::SpeakerAddListener
|
|
||||||
//
|
|
||||||
bool LLPanelActiveSpeakers::SpeakerAddListener::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
|
||||||
{
|
|
||||||
mPanel->addSpeaker(event->getValue().asUUID());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// LLPanelActiveSpeakers::SpeakerRemoveListener
|
|
||||||
//
|
|
||||||
bool LLPanelActiveSpeakers::SpeakerRemoveListener::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
|
||||||
{
|
|
||||||
mPanel->removeSpeaker(event->getValue().asUUID());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// LLPanelActiveSpeakers::SpeakerClearListener
|
|
||||||
//
|
|
||||||
bool LLPanelActiveSpeakers::SpeakerClearListener::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
|
||||||
{
|
|
||||||
mPanel->mSpeakerList->clearRows();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// LLPanelActiveSpeakers
|
|
||||||
//
|
|
||||||
LLPanelActiveSpeakers::LLPanelActiveSpeakers(LLSpeakerMgr* data_source, BOOL show_text_chatters) :
|
|
||||||
mSpeakerList(NULL),
|
|
||||||
mMuteVoiceCtrl(NULL),
|
|
||||||
mMuteTextCtrl(NULL),
|
|
||||||
mNameText(NULL),
|
|
||||||
mProfileBtn(NULL),
|
|
||||||
mShowTextChatters(show_text_chatters),
|
|
||||||
mSpeakerMgr(data_source)
|
|
||||||
{
|
|
||||||
setMouseOpaque(FALSE);
|
|
||||||
mSpeakerMuteListener = new SpeakerMuteListener(this);
|
|
||||||
mSpeakerAddListener = new SpeakerAddListener(this);
|
|
||||||
mSpeakerRemoveListener = new SpeakerRemoveListener(this);
|
|
||||||
mSpeakerClearListener = new SpeakerClearListener(this);
|
|
||||||
|
|
||||||
mSpeakerMgr->addListener(mSpeakerAddListener, "add");
|
|
||||||
mSpeakerMgr->addListener(mSpeakerRemoveListener, "remove");
|
|
||||||
mSpeakerMgr->addListener(mSpeakerClearListener, "clear");
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL LLPanelActiveSpeakers::postBuild()
|
|
||||||
{
|
|
||||||
std::string sort_column = gSavedSettings.getString(std::string("FloaterActiveSpeakersSortColumn"));
|
|
||||||
BOOL sort_ascending = gSavedSettings.getBOOL( std::string("FloaterActiveSpeakersSortAscending"));
|
|
||||||
|
|
||||||
mSpeakerList = getChild<LLScrollListCtrl>("speakers_list");
|
|
||||||
mSpeakerList->sortByColumn(sort_column, sort_ascending);
|
|
||||||
mSpeakerList->setDoubleClickCallback(boost::bind(&onDoubleClickSpeaker,this));
|
|
||||||
mSpeakerList->setCommitOnSelectionChange(TRUE);
|
|
||||||
mSpeakerList->setCommitCallback(boost::bind(&LLPanelActiveSpeakers::handleSpeakerSelect,this));
|
|
||||||
mSpeakerList->setSortChangedCallback(boost::bind(&LLPanelActiveSpeakers::onSortChanged,this));
|
|
||||||
mSpeakerList->setCallbackUserData(this);
|
|
||||||
|
|
||||||
if ((mMuteTextCtrl = findChild<LLUICtrl>("mute_text_btn")))
|
|
||||||
childSetCommitCallback("mute_text_btn", onClickMuteTextCommit, this);
|
|
||||||
|
|
||||||
mMuteVoiceCtrl = getChild<LLUICtrl>("mute_btn");
|
|
||||||
childSetCommitCallback("mute_btn", onClickMuteVoiceCommit, this);
|
|
||||||
|
|
||||||
childSetCommitCallback("speaker_volume", onVolumeChange, this);
|
|
||||||
|
|
||||||
mNameText = findChild<LLTextBox>("resident_name");
|
|
||||||
|
|
||||||
if ((mProfileBtn = findChild<LLButton>("profile_btn")))
|
|
||||||
childSetAction("profile_btn", onClickProfile, this);
|
|
||||||
|
|
||||||
if (findChild<LLUICtrl>("moderator_allow_voice"))
|
|
||||||
childSetCommitCallback("moderator_allow_voice", onModeratorMuteVoice, this);
|
|
||||||
if (findChild<LLUICtrl>("moderator_allow_text"))
|
|
||||||
childSetCommitCallback("moderator_allow_text", onModeratorMuteText, this);
|
|
||||||
if (findChild<LLUICtrl>("moderator_mode"))
|
|
||||||
childSetCommitCallback("moderation_mode", onChangeModerationMode, this);
|
|
||||||
|
|
||||||
mVolumeSlider.connect(this,"speaker_volume");
|
|
||||||
|
|
||||||
// update speaker UI
|
|
||||||
handleSpeakerSelect();
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LLPanelActiveSpeakers::addSpeaker(const LLUUID& speaker_id)
|
|
||||||
{
|
|
||||||
if (mSpeakerList->getItemIndex(speaker_id) >= 0)
|
|
||||||
{
|
|
||||||
// already have this speaker
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LLPointer<LLSpeaker> speakerp = mSpeakerMgr->findSpeaker(speaker_id);
|
|
||||||
if (speakerp)
|
|
||||||
{
|
|
||||||
// since we are forced to sort by text, encode sort order as string
|
|
||||||
std::string speaking_order_sort_string = llformat("%010d", speakerp->mSortIndex);
|
|
||||||
|
|
||||||
LLSD row;
|
|
||||||
row["id"] = speaker_id;
|
|
||||||
|
|
||||||
LLSD& columns = row["columns"];
|
|
||||||
|
|
||||||
columns[0]["column"] = "icon_speaking_status";
|
|
||||||
columns[0]["type"] = "icon";
|
|
||||||
columns[0]["value"] = "icn_active-speakers-dot-lvl0.tga";
|
|
||||||
|
|
||||||
std::string speaker_name;
|
|
||||||
if (speakerp->mDisplayName.empty())
|
|
||||||
{
|
|
||||||
speaker_name = LLCacheName::getDefaultName();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
speaker_name = speakerp->mDisplayName;
|
|
||||||
}
|
|
||||||
columns[1]["column"] = "speaker_name";
|
|
||||||
columns[1]["type"] = "text";
|
|
||||||
columns[1]["value"] = speaker_name;
|
|
||||||
|
|
||||||
columns[2]["column"] = "speaking_status";
|
|
||||||
columns[2]["type"] = "text";
|
|
||||||
|
|
||||||
// print speaking ordinal in a text-sorting friendly manner
|
|
||||||
columns[2]["value"] = speaking_order_sort_string;
|
|
||||||
|
|
||||||
mSpeakerList->addElement(row);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LLPanelActiveSpeakers::removeSpeaker(const LLUUID& speaker_id)
|
|
||||||
{
|
|
||||||
mSpeakerList->deleteSingleItem(mSpeakerList->getItemIndex(speaker_id));
|
|
||||||
}
|
|
||||||
|
|
||||||
void LLPanelActiveSpeakers::handleSpeakerSelect()
|
|
||||||
{
|
|
||||||
LLUUID speaker_id = mSpeakerList->getValue().asUUID();
|
|
||||||
LLPointer<LLSpeaker> selected_speakerp = mSpeakerMgr->findSpeaker(speaker_id);
|
|
||||||
|
|
||||||
if (selected_speakerp.notNull())
|
|
||||||
{
|
|
||||||
// since setting these values is delayed by a round trip to the Vivox servers
|
|
||||||
// update them only when selecting a new speaker or
|
|
||||||
// asynchronously when an update arrives
|
|
||||||
childSetValue("moderator_allow_voice", selected_speakerp ? !selected_speakerp->mModeratorMutedVoice : TRUE);
|
|
||||||
childSetValue("moderator_allow_text", selected_speakerp ? !selected_speakerp->mModeratorMutedText : TRUE);
|
|
||||||
|
|
||||||
mSpeakerMuteListener->clearDispatchers();
|
|
||||||
selected_speakerp->addListener(mSpeakerMuteListener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LLPanelActiveSpeakers::refreshSpeakers()
|
|
||||||
{
|
|
||||||
// store off current selection and scroll state to preserve across list rebuilds
|
|
||||||
LLUUID selected_id = mSpeakerList->getSelectedValue().asUUID();
|
|
||||||
S32 scroll_pos = mSpeakerList->getScrollInterface()->getScrollPos();
|
|
||||||
|
|
||||||
// decide whether it's ok to resort the list then update the speaker manager appropriately.
|
|
||||||
// rapid resorting by activity makes it hard to interact with speakers in the list
|
|
||||||
// so we freeze the sorting while the user appears to be interacting with the control.
|
|
||||||
// we assume this is the case whenever the mouse pointer is within the active speaker
|
|
||||||
// panel and hasn't been motionless for more than a few seconds. see DEV-6655 -MG
|
|
||||||
LLRect screen_rect;
|
|
||||||
localRectToScreen(getLocalRect(), &screen_rect);
|
|
||||||
BOOL mouse_in_view = screen_rect.pointInRect(gViewerWindow->getCurrentMouseX(), gViewerWindow->getCurrentMouseY());
|
|
||||||
F32 mouses_last_movement = gMouseIdleTimer.getElapsedTimeF32();
|
|
||||||
BOOL sort_ok = ! (mouse_in_view && mouses_last_movement<RESORT_TIMEOUT);
|
|
||||||
mSpeakerMgr->update(sort_ok);
|
|
||||||
|
|
||||||
const std::string icon_image_0 = "icn_active-speakers-dot-lvl0.tga";
|
|
||||||
const std::string icon_image_1 = "icn_active-speakers-dot-lvl1.tga";
|
|
||||||
const std::string icon_image_2 = "icn_active-speakers-dot-lvl2.tga";
|
|
||||||
|
|
||||||
std::vector<LLScrollListItem*> items = mSpeakerList->getAllData();
|
|
||||||
|
|
||||||
std::string mute_icon_image = "mute_icon.tga";
|
|
||||||
|
|
||||||
LLSpeakerMgr::speaker_list_t speaker_list;
|
|
||||||
mSpeakerMgr->getSpeakerList(&speaker_list, mShowTextChatters);
|
|
||||||
for (std::vector<LLScrollListItem*>::iterator item_it = items.begin();
|
|
||||||
item_it != items.end();
|
|
||||||
++item_it)
|
|
||||||
{
|
|
||||||
LLScrollListItem* itemp = (*item_it);
|
|
||||||
LLUUID speaker_id = itemp->getUUID();
|
|
||||||
|
|
||||||
LLPointer<LLSpeaker> speakerp = mSpeakerMgr->findSpeaker(speaker_id);
|
|
||||||
if (!speakerp)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// since we are forced to sort by text, encode sort order as string
|
|
||||||
std::string speaking_order_sort_string = llformat("%010d", speakerp->mSortIndex);
|
|
||||||
|
|
||||||
LLScrollListCell* icon_cell = itemp->getColumn(0);
|
|
||||||
if (icon_cell)
|
|
||||||
{
|
|
||||||
|
|
||||||
std::string icon_image_id;
|
|
||||||
|
|
||||||
S32 icon_image_idx = llmin(2, llfloor((speakerp->mSpeechVolume / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 3.f));
|
|
||||||
switch(icon_image_idx)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
icon_image_id = icon_image_0;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
icon_image_id = icon_image_1;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
icon_image_id = icon_image_2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
LLColor4 icon_color;
|
|
||||||
|
|
||||||
if (speakerp->mStatus == LLSpeaker::STATUS_MUTED)
|
|
||||||
{
|
|
||||||
icon_cell->setValue(mute_icon_image);
|
|
||||||
if(speakerp->mModeratorMutedVoice)
|
|
||||||
{
|
|
||||||
icon_color.setVec(0.5f, 0.5f, 0.5f, 1.f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
icon_color.setVec(1.f, 71.f / 255.f, 71.f / 255.f, 1.f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
icon_cell->setValue(icon_image_id);
|
|
||||||
icon_color = speakerp->mDotColor;
|
|
||||||
|
|
||||||
if (speakerp->mStatus > LLSpeaker::STATUS_VOICE_ACTIVE) // if voice is disabled for this speaker
|
|
||||||
{
|
|
||||||
// non voice speakers have hidden icons, render as transparent
|
|
||||||
icon_color.setVec(0.f, 0.f, 0.f, 0.f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
icon_cell->setColor(icon_color);
|
|
||||||
|
|
||||||
if (speakerp->mStatus > LLSpeaker::STATUS_VOICE_ACTIVE && speakerp->mStatus != LLSpeaker::STATUS_MUTED) // if voice is disabled for this speaker
|
|
||||||
{
|
|
||||||
// non voice speakers have hidden icons, render as transparent
|
|
||||||
icon_cell->setColor(LLColor4::transparent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// update name column
|
|
||||||
LLScrollListCell* name_cell = itemp->getColumn(1);
|
|
||||||
if (name_cell)
|
|
||||||
{
|
|
||||||
if (speakerp->mStatus == LLSpeaker::STATUS_NOT_IN_CHANNEL)
|
|
||||||
{
|
|
||||||
// draw inactive speakers in different color
|
|
||||||
static LLCachedControl<LLColor4> sSpeakersInactive(gColors, "SpeakersInactive");
|
|
||||||
|
|
||||||
name_cell->setColor(sSpeakersInactive);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
static LLCachedControl<LLColor4> sDefaultListText(gColors, "DefaultListText");
|
|
||||||
|
|
||||||
name_cell->setColor(sDefaultListText);
|
|
||||||
}
|
|
||||||
// <edit>
|
|
||||||
if(!mShowTextChatters && !(speakerp->mStatus == LLSpeaker::STATUS_NOT_IN_CHANNEL) && speakerp->mID != gAgent.getID())
|
|
||||||
{
|
|
||||||
bool found = false;
|
|
||||||
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
|
|
||||||
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
|
|
||||||
{
|
|
||||||
LLViewerRegion* regionp = *iter;
|
|
||||||
// let us check to see if they are actually in the sim
|
|
||||||
if(regionp)
|
|
||||||
{
|
|
||||||
if(regionp->mMapAvatarIDs.find(speakerp->mID) != -1)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!found)
|
|
||||||
{
|
|
||||||
static LLCachedControl<LLColor4> sSpeakersGhost(gColors, "SpeakersGhost");
|
|
||||||
|
|
||||||
name_cell->setColor(sSpeakersGhost);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// </edit>
|
|
||||||
|
|
||||||
std::string speaker_name;
|
|
||||||
if (speakerp->mDisplayName.empty())
|
|
||||||
{
|
|
||||||
speaker_name = LLCacheName::getDefaultName();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
speaker_name = speakerp->mDisplayName;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (speakerp->mIsModerator)
|
|
||||||
{
|
|
||||||
speaker_name += std::string(" ") + getString("moderator_label");
|
|
||||||
}
|
|
||||||
|
|
||||||
name_cell->setValue(speaker_name);
|
|
||||||
((LLScrollListText*)name_cell)->setFontStyle(speakerp->mIsModerator ? LLFontGL::BOLD : LLFontGL::NORMAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update speaking order column
|
|
||||||
LLScrollListCell* speaking_status_cell = itemp->getColumn(2);
|
|
||||||
if (speaking_status_cell)
|
|
||||||
{
|
|
||||||
// print speaking ordinal in a text-sorting friendly manner
|
|
||||||
speaking_status_cell->setValue(speaking_order_sort_string);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// we potentially modified the sort order by touching the list items
|
|
||||||
mSpeakerList->setNeedsSort();
|
|
||||||
|
|
||||||
LLPointer<LLSpeaker> selected_speakerp = mSpeakerMgr->findSpeaker(selected_id);
|
|
||||||
// update UI for selected participant
|
|
||||||
if (mMuteVoiceCtrl)
|
|
||||||
{
|
|
||||||
mMuteVoiceCtrl->setValue(LLMuteList::getInstance()->isMuted(selected_id, LLMute::flagVoiceChat));
|
|
||||||
mMuteVoiceCtrl->setEnabled(LLVoiceClient::getInstance()->voiceEnabled()
|
|
||||||
&& LLVoiceClient::getInstance()->getVoiceEnabled(selected_id)
|
|
||||||
&& selected_id.notNull()
|
|
||||||
&& selected_id != gAgent.getID()
|
|
||||||
&& (selected_speakerp.notNull() && (selected_speakerp->mType == LLSpeaker::SPEAKER_AGENT || selected_speakerp->mType == LLSpeaker::SPEAKER_EXTERNAL)));
|
|
||||||
|
|
||||||
}
|
|
||||||
if (mMuteTextCtrl)
|
|
||||||
{
|
|
||||||
mMuteTextCtrl->setValue(LLMuteList::getInstance()->isMuted(selected_id, LLMute::flagTextChat));
|
|
||||||
mMuteTextCtrl->setEnabled(selected_id.notNull()
|
|
||||||
&& selected_id != gAgent.getID()
|
|
||||||
&& selected_speakerp.notNull()
|
|
||||||
&& selected_speakerp->mType != LLSpeaker::SPEAKER_EXTERNAL
|
|
||||||
&& !LLMuteList::getInstance()->isLinden(selected_id));
|
|
||||||
}
|
|
||||||
mVolumeSlider->setValue(LLVoiceClient::getInstance()->getUserVolume(selected_id));
|
|
||||||
mVolumeSlider->setEnabled(LLVoiceClient::getInstance()->voiceEnabled()
|
|
||||||
&& LLVoiceClient::getInstance()->getVoiceEnabled(selected_id)
|
|
||||||
&& selected_id.notNull()
|
|
||||||
&& selected_id != gAgent.getID()
|
|
||||||
&& (selected_speakerp.notNull() && (selected_speakerp->mType == LLSpeaker::SPEAKER_AGENT || selected_speakerp->mType == LLSpeaker::SPEAKER_EXTERNAL)));
|
|
||||||
|
|
||||||
if (LLView* view = findChild<LLView>("moderator_controls_label"))
|
|
||||||
view->setEnabled(selected_id.notNull());
|
|
||||||
|
|
||||||
if (LLView* view = findChild<LLView>("moderator_allow_voice"))
|
|
||||||
view->setEnabled(selected_id.notNull() && mSpeakerMgr->isVoiceActive() && LLVoiceClient::getInstance()->getVoiceEnabled(selected_id));
|
|
||||||
|
|
||||||
if (LLView* view = findChild<LLView>("moderator_allow_text"))
|
|
||||||
view->setEnabled(selected_id.notNull());
|
|
||||||
|
|
||||||
if (mProfileBtn)
|
|
||||||
{
|
|
||||||
mProfileBtn->setEnabled(selected_id.notNull() && (selected_speakerp.notNull() && selected_speakerp->mType != LLSpeaker::SPEAKER_EXTERNAL) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// show selected user name in large font
|
|
||||||
if (mNameText)
|
|
||||||
{
|
|
||||||
if (selected_speakerp)
|
|
||||||
{
|
|
||||||
mNameText->setValue(selected_speakerp->mDisplayName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mNameText->setValue(LLStringUtil::null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//update moderator capabilities
|
|
||||||
LLPointer<LLSpeaker> self_speakerp = mSpeakerMgr->findSpeaker(gAgent.getID());
|
|
||||||
if(self_speakerp)
|
|
||||||
{
|
|
||||||
if (LLView* view = findChild<LLView>("moderation_mode_panel"))
|
|
||||||
view->setVisible(self_speakerp->mIsModerator && mSpeakerMgr->isVoiceActive());
|
|
||||||
if (LLView* view = findChild<LLView>("moderator_controls"))
|
|
||||||
view->setVisible(self_speakerp->mIsModerator);
|
|
||||||
}
|
|
||||||
|
|
||||||
// keep scroll value stable
|
|
||||||
mSpeakerList->getScrollInterface()->setScrollPos(scroll_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LLPanelActiveSpeakers::setVoiceModerationCtrlMode(
|
|
||||||
const BOOL& moderated_voice)
|
|
||||||
{
|
|
||||||
LLUICtrl* voice_moderation_ctrl = getChild<LLUICtrl>("moderation_mode");
|
|
||||||
|
|
||||||
if ( voice_moderation_ctrl )
|
|
||||||
{
|
|
||||||
std::string value;
|
|
||||||
|
|
||||||
value = moderated_voice ? "moderated" : "unmoderated";
|
|
||||||
voice_moderation_ctrl->setValue(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
void LLPanelActiveSpeakers::onClickMuteTextCommit(LLUICtrl* ctrl, void* user_data)
|
|
||||||
{
|
|
||||||
LLPanelActiveSpeakers* panelp = (LLPanelActiveSpeakers*)user_data;
|
|
||||||
LLUUID speaker_id = panelp->mSpeakerList->getValue().asUUID();
|
|
||||||
BOOL is_muted = LLMuteList::getInstance()->isMuted(speaker_id, LLMute::flagTextChat);
|
|
||||||
std::string name;
|
|
||||||
|
|
||||||
//fill in name using voice client's copy of name cache
|
|
||||||
LLPointer<LLSpeaker> speakerp = panelp->mSpeakerMgr->findSpeaker(speaker_id);
|
|
||||||
if (speakerp.isNull())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
name = speakerp->mDisplayName;
|
|
||||||
|
|
||||||
LLMute mute(speaker_id, name, speakerp->mType == LLSpeaker::SPEAKER_AGENT ? LLMute::AGENT : LLMute::OBJECT);
|
|
||||||
|
|
||||||
if (!is_muted)
|
|
||||||
{
|
|
||||||
LLMuteList::getInstance()->add(mute, LLMute::flagTextChat);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LLMuteList::getInstance()->remove(mute, LLMute::flagTextChat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//static
|
|
||||||
void LLPanelActiveSpeakers::onClickMuteVoiceCommit(LLUICtrl* ctrl, void* user_data)
|
|
||||||
{
|
|
||||||
LLPanelActiveSpeakers* panelp = (LLPanelActiveSpeakers*)user_data;
|
|
||||||
LLUUID speaker_id = panelp->mSpeakerList->getValue().asUUID();
|
|
||||||
BOOL is_muted = LLMuteList::getInstance()->isMuted(speaker_id, LLMute::flagVoiceChat);
|
|
||||||
std::string name;
|
|
||||||
|
|
||||||
LLPointer<LLSpeaker> speakerp = panelp->mSpeakerMgr->findSpeaker(speaker_id);
|
|
||||||
if (speakerp.isNull())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
name = speakerp->mDisplayName;
|
|
||||||
|
|
||||||
// muting voice means we're dealing with an agent or an external voice client which won't stay muted between sessions
|
|
||||||
LLMute mute(speaker_id, name, speakerp->mType == LLSpeaker::SPEAKER_EXTERNAL ? LLMute::EXTERNAL : LLMute::AGENT);
|
|
||||||
|
|
||||||
if (!is_muted)
|
|
||||||
{
|
|
||||||
LLMuteList::getInstance()->add(mute, LLMute::flagVoiceChat);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LLMuteList::getInstance()->remove(mute, LLMute::flagVoiceChat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//static
|
|
||||||
void LLPanelActiveSpeakers::onVolumeChange(LLUICtrl* source, void* user_data)
|
|
||||||
{
|
|
||||||
LLPanelActiveSpeakers* panelp = (LLPanelActiveSpeakers*)user_data;
|
|
||||||
LLUUID speaker_id = panelp->mSpeakerList->getValue().asUUID();
|
|
||||||
|
|
||||||
F32 new_volume = (F32)panelp->childGetValue("speaker_volume").asReal();
|
|
||||||
LLVoiceClient::getInstance()->setUserVolume(speaker_id, new_volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
void LLPanelActiveSpeakers::onClickProfile(void* user_data)
|
|
||||||
{
|
|
||||||
// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-1.0.0g
|
|
||||||
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// [/RLVa:KB]
|
|
||||||
|
|
||||||
LLPanelActiveSpeakers* panelp = (LLPanelActiveSpeakers*)user_data;
|
|
||||||
LLAvatarActions::showProfile(panelp->mSpeakerList->getValue().asUUID());
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
void LLPanelActiveSpeakers::onDoubleClickSpeaker(void* user_data)
|
|
||||||
{
|
|
||||||
LLPanelActiveSpeakers* panelp = (LLPanelActiveSpeakers*)user_data;
|
|
||||||
LLAvatarActions::startIM(panelp->mSpeakerList->getValue().asUUID());
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
void LLPanelActiveSpeakers::onSortChanged(void* user_data)
|
|
||||||
{
|
|
||||||
LLPanelActiveSpeakers* panelp = (LLPanelActiveSpeakers*)user_data;
|
|
||||||
std::string sort_column = panelp->mSpeakerList->getSortColumnName();
|
|
||||||
BOOL sort_ascending = panelp->mSpeakerList->getSortAscending();
|
|
||||||
gSavedSettings.setString(std::string("FloaterActiveSpeakersSortColumn"), sort_column);
|
|
||||||
gSavedSettings.setBOOL( std::string("FloaterActiveSpeakersSortAscending"), sort_ascending);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//static
|
|
||||||
void LLPanelActiveSpeakers::onModeratorMuteVoice(LLUICtrl* ctrl, void* user_data)
|
|
||||||
{
|
|
||||||
LLPanelActiveSpeakers* self = (LLPanelActiveSpeakers*)user_data;
|
|
||||||
LLUICtrl* speakers_list = self->getChild<LLUICtrl>("speakers_list");
|
|
||||||
if (!speakers_list || !gAgent.getRegion()) return;
|
|
||||||
if (LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(self->mSpeakerMgr))
|
|
||||||
mgr->moderateVoiceParticipant(speakers_list->getValue(), ctrl->getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
void LLPanelActiveSpeakers::onModeratorMuteText(LLUICtrl* ctrl, void* user_data)
|
|
||||||
{
|
|
||||||
LLPanelActiveSpeakers* self = (LLPanelActiveSpeakers*)user_data;
|
|
||||||
LLUICtrl* speakers_list = self->getChild<LLUICtrl>("speakers_list");
|
|
||||||
if (!speakers_list || !gAgent.getRegion()) return;
|
|
||||||
if (LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(self->mSpeakerMgr))
|
|
||||||
mgr->toggleAllowTextChat(speakers_list->getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
//static
|
|
||||||
void LLPanelActiveSpeakers::onChangeModerationMode(LLUICtrl* ctrl, void* user_data)
|
|
||||||
{
|
|
||||||
LLPanelActiveSpeakers* self = (LLPanelActiveSpeakers*)user_data;
|
|
||||||
if (!gAgent.getRegion()) return;
|
|
||||||
// Singu Note: moderateVoiceAllParticipants ends up flipping the boolean passed to it before the actual post
|
|
||||||
if (LLIMSpeakerMgr* speaker_manager = dynamic_cast<LLIMSpeakerMgr*>(self->mSpeakerMgr))
|
|
||||||
{
|
|
||||||
if (ctrl->getValue().asString() == "unmoderated")
|
|
||||||
{
|
|
||||||
speaker_manager->moderateVoiceAllParticipants(true);
|
|
||||||
}
|
|
||||||
else if (ctrl->getValue().asString() == "moderated")
|
|
||||||
{
|
|
||||||
speaker_manager->moderateVoiceAllParticipants(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,15 +34,8 @@
|
|||||||
|
|
||||||
#include "llfloater.h"
|
#include "llfloater.h"
|
||||||
#include "llvoiceclient.h"
|
#include "llvoiceclient.h"
|
||||||
#include "llframetimer.h"
|
|
||||||
#include "llevent.h"
|
|
||||||
|
|
||||||
class LLScrollListCtrl;
|
|
||||||
class LLButton;
|
|
||||||
class LLPanelActiveSpeakers;
|
|
||||||
class LLSpeakerMgr;
|
|
||||||
class LLTextBox;
|
|
||||||
|
|
||||||
|
class LLParticipantList;
|
||||||
|
|
||||||
class LLFloaterActiveSpeakers :
|
class LLFloaterActiveSpeakers :
|
||||||
public LLFloaterSingleton<LLFloaterActiveSpeakers>,
|
public LLFloaterSingleton<LLFloaterActiveSpeakers>,
|
||||||
@@ -67,95 +60,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
LLFloaterActiveSpeakers(const LLSD& seed);
|
LLFloaterActiveSpeakers(const LLSD& seed);
|
||||||
|
|
||||||
LLPanelActiveSpeakers* mPanel;
|
LLParticipantList* mPanel;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LLPanelActiveSpeakers : public LLPanel
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LLPanelActiveSpeakers(LLSpeakerMgr* data_source, BOOL show_text_chatters);
|
|
||||||
|
|
||||||
/*virtual*/ BOOL postBuild();
|
|
||||||
|
|
||||||
void handleSpeakerSelect();
|
|
||||||
void refreshSpeakers();
|
|
||||||
|
|
||||||
void setVoiceModerationCtrlMode(const BOOL& moderated_voice);
|
|
||||||
|
|
||||||
static void onClickMuteVoiceCommit(LLUICtrl* ctrl, void* user_data);
|
|
||||||
static void onClickMuteTextCommit(LLUICtrl* ctrl, void* user_data);
|
|
||||||
static void onVolumeChange(LLUICtrl* source, void* user_data);
|
|
||||||
static void onClickProfile(void* user_data);
|
|
||||||
static void onDoubleClickSpeaker(void* user_data);
|
|
||||||
static void onSortChanged(void* user_data);
|
|
||||||
static void onModeratorMuteVoice(LLUICtrl* ctrl, void* user_data);
|
|
||||||
static void onModeratorMuteText(LLUICtrl* ctrl, void* user_data);
|
|
||||||
static void onChangeModerationMode(LLUICtrl* ctrl, void* user_data);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
class SpeakerMuteListener : public LLOldEvents::LLSimpleListener
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SpeakerMuteListener(LLPanelActiveSpeakers* panel) : mPanel(panel) {}
|
|
||||||
|
|
||||||
/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
|
|
||||||
|
|
||||||
LLPanelActiveSpeakers* mPanel;
|
|
||||||
};
|
|
||||||
|
|
||||||
friend class SpeakerAddListener;
|
|
||||||
class SpeakerAddListener : public LLOldEvents::LLSimpleListener
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SpeakerAddListener(LLPanelActiveSpeakers* panel) : mPanel(panel) {}
|
|
||||||
|
|
||||||
/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
|
|
||||||
|
|
||||||
LLPanelActiveSpeakers* mPanel;
|
|
||||||
};
|
|
||||||
|
|
||||||
friend class SpeakerRemoveListener;
|
|
||||||
class SpeakerRemoveListener : public LLOldEvents::LLSimpleListener
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SpeakerRemoveListener(LLPanelActiveSpeakers* panel) : mPanel(panel) {}
|
|
||||||
|
|
||||||
/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
|
|
||||||
|
|
||||||
LLPanelActiveSpeakers* mPanel;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
friend class SpeakerClearListener;
|
|
||||||
class SpeakerClearListener : public LLOldEvents::LLSimpleListener
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SpeakerClearListener(LLPanelActiveSpeakers* panel) : mPanel(panel) {}
|
|
||||||
|
|
||||||
/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
|
|
||||||
|
|
||||||
LLPanelActiveSpeakers* mPanel;
|
|
||||||
};
|
|
||||||
|
|
||||||
void addSpeaker(const LLUUID& id);
|
|
||||||
void removeSpeaker(const LLUUID& id);
|
|
||||||
|
|
||||||
|
|
||||||
LLScrollListCtrl* mSpeakerList;
|
|
||||||
LLUICtrl* mMuteVoiceCtrl;
|
|
||||||
LLUICtrl* mMuteTextCtrl;
|
|
||||||
LLTextBox* mNameText;
|
|
||||||
LLButton* mProfileBtn;
|
|
||||||
BOOL mShowTextChatters;
|
|
||||||
LLSpeakerMgr* mSpeakerMgr;
|
|
||||||
LLFrameTimer mIconAnimationTimer;
|
|
||||||
LLPointer<SpeakerMuteListener> mSpeakerMuteListener;
|
|
||||||
LLPointer<SpeakerAddListener> mSpeakerAddListener;
|
|
||||||
LLPointer<SpeakerRemoveListener> mSpeakerRemoveListener;
|
|
||||||
LLPointer<SpeakerClearListener> mSpeakerClearListener;
|
|
||||||
|
|
||||||
CachedUICtrl<LLUICtrl> mVolumeSlider;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // LL_LLFLOATERACTIVESPEAKERS_H
|
#endif // LL_LLFLOATERACTIVESPEAKERS_H
|
||||||
|
|||||||
@@ -52,12 +52,12 @@
|
|||||||
#include "llagent.h"
|
#include "llagent.h"
|
||||||
#include "llchatbar.h"
|
#include "llchatbar.h"
|
||||||
#include "llconsole.h"
|
#include "llconsole.h"
|
||||||
#include "llfloateractivespeakers.h"
|
|
||||||
#include "llfloaterchatterbox.h"
|
#include "llfloaterchatterbox.h"
|
||||||
#include "llfloatermute.h"
|
#include "llfloatermute.h"
|
||||||
#include "llfloaterscriptdebug.h"
|
#include "llfloaterscriptdebug.h"
|
||||||
#include "lllogchat.h"
|
#include "lllogchat.h"
|
||||||
#include "llmutelist.h"
|
#include "llmutelist.h"
|
||||||
|
#include "llparticipantlist.h"
|
||||||
#include "llspeakers.h"
|
#include "llspeakers.h"
|
||||||
#include "llstylemap.h"
|
#include "llstylemap.h"
|
||||||
#include "lluictrlfactory.h"
|
#include "lluictrlfactory.h"
|
||||||
@@ -127,7 +127,7 @@ void LLFloaterChat::draw()
|
|||||||
|
|
||||||
BOOL LLFloaterChat::postBuild()
|
BOOL LLFloaterChat::postBuild()
|
||||||
{
|
{
|
||||||
mPanel = (LLPanelActiveSpeakers*)getChild<LLPanel>("active_speakers_panel");
|
mPanel = getChild<LLParticipantList>("active_speakers_panel");
|
||||||
|
|
||||||
LLChatBar* chat_barp = getChild<LLChatBar>("chat_panel", TRUE);
|
LLChatBar* chat_barp = getChild<LLChatBar>("chat_panel", TRUE);
|
||||||
if (chat_barp)
|
if (chat_barp)
|
||||||
@@ -628,7 +628,7 @@ void LLFloaterChat::chatFromLogFile(LLLogChat::ELogLineType type , std::string l
|
|||||||
//static
|
//static
|
||||||
void* LLFloaterChat::createSpeakersPanel(void* data)
|
void* LLFloaterChat::createSpeakersPanel(void* data)
|
||||||
{
|
{
|
||||||
return new LLPanelActiveSpeakers(LLLocalSpeakerMgr::getInstance(), TRUE);
|
return new LLParticipantList(LLLocalSpeakerMgr::getInstance(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
//static
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class LLViewerTextEditor;
|
|||||||
class LLMessageSystem;
|
class LLMessageSystem;
|
||||||
class LLUUID;
|
class LLUUID;
|
||||||
class LLCheckBoxCtrl;
|
class LLCheckBoxCtrl;
|
||||||
class LLPanelActiveSpeakers;
|
class LLParticipantList;
|
||||||
class LLLogChat;
|
class LLLogChat;
|
||||||
class LLChatBar;
|
class LLChatBar;
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ public:
|
|||||||
static void show(LLFloater* instance, const LLSD& key);
|
static void show(LLFloater* instance, const LLSD& key);
|
||||||
static void hide(LLFloater* instance, const LLSD& key);
|
static void hide(LLFloater* instance, const LLSD& key);
|
||||||
|
|
||||||
LLPanelActiveSpeakers* mPanel;
|
LLParticipantList* mPanel;
|
||||||
BOOL mScrolledToEnd;
|
BOOL mScrolledToEnd;
|
||||||
|
|
||||||
BOOL focusFirstItem(BOOL prefer_text_fields = FALSE, BOOL focus_flash = TRUE );
|
BOOL focusFirstItem(BOOL prefer_text_fields = FALSE, BOOL focus_flash = TRUE );
|
||||||
|
|||||||
@@ -50,7 +50,6 @@
|
|||||||
#include "llchat.h"
|
#include "llchat.h"
|
||||||
#include "llconsole.h"
|
#include "llconsole.h"
|
||||||
#include "llgroupactions.h"
|
#include "llgroupactions.h"
|
||||||
#include "llfloateractivespeakers.h"
|
|
||||||
#include "llfloaterchat.h"
|
#include "llfloaterchat.h"
|
||||||
#include "llimview.h"
|
#include "llimview.h"
|
||||||
#include "llinventory.h"
|
#include "llinventory.h"
|
||||||
@@ -60,6 +59,7 @@
|
|||||||
#include "llkeyboard.h"
|
#include "llkeyboard.h"
|
||||||
#include "lllineeditor.h"
|
#include "lllineeditor.h"
|
||||||
#include "llnotify.h"
|
#include "llnotify.h"
|
||||||
|
#include "llparticipantlist.h"
|
||||||
#include "llresmgr.h"
|
#include "llresmgr.h"
|
||||||
#include "llspeakers.h"
|
#include "llspeakers.h"
|
||||||
#include "lltrans.h"
|
#include "lltrans.h"
|
||||||
@@ -621,7 +621,7 @@ BOOL LLFloaterIMPanel::postBuild()
|
|||||||
void* LLFloaterIMPanel::createSpeakersPanel(void* data)
|
void* LLFloaterIMPanel::createSpeakersPanel(void* data)
|
||||||
{
|
{
|
||||||
LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)data;
|
LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)data;
|
||||||
floaterp->mSpeakerPanel = new LLPanelActiveSpeakers(floaterp->mSpeakers, TRUE);
|
floaterp->mSpeakerPanel = new LLParticipantList(floaterp->mSpeakers, true);
|
||||||
return floaterp->mSpeakerPanel;
|
return floaterp->mSpeakerPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,8 +46,7 @@ class LLViewerTextEditor;
|
|||||||
class LLInventoryItem;
|
class LLInventoryItem;
|
||||||
class LLInventoryCategory;
|
class LLInventoryCategory;
|
||||||
class LLIMSpeakerMgr;
|
class LLIMSpeakerMgr;
|
||||||
class LLPanelActiveSpeakers;
|
class LLParticipantList;
|
||||||
class LLPanel;
|
|
||||||
class LLButton;
|
class LLButton;
|
||||||
class LLVoiceChannel;
|
class LLVoiceChannel;
|
||||||
|
|
||||||
@@ -244,7 +243,7 @@ private:
|
|||||||
BOOL mCallBackEnabled;
|
BOOL mCallBackEnabled;
|
||||||
|
|
||||||
LLIMSpeakerMgr* mSpeakers;
|
LLIMSpeakerMgr* mSpeakers;
|
||||||
LLPanelActiveSpeakers* mSpeakerPanel;
|
LLParticipantList* mSpeakerPanel;
|
||||||
|
|
||||||
// Optimization: Don't send "User is typing..." until the
|
// Optimization: Don't send "User is typing..." until the
|
||||||
// user has actually been typing for a little while. Prevents
|
// user has actually been typing for a little while. Prevents
|
||||||
|
|||||||
597
indra/newview/llparticipantlist.cpp
Normal file
597
indra/newview/llparticipantlist.cpp
Normal file
@@ -0,0 +1,597 @@
|
|||||||
|
/**
|
||||||
|
* @file llparticipantlist.cpp
|
||||||
|
* @brief LLParticipantList intended to update view(LLAvatarList) according to incoming messages
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
|
||||||
|
* Second Life Viewer Source Code
|
||||||
|
* Copyright (C) 2010, Linden Research, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation;
|
||||||
|
* version 2.1 of the License only.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||||
|
* $/LicenseInfo$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "llviewerprecompiledheaders.h"
|
||||||
|
|
||||||
|
#include "llavataractions.h"
|
||||||
|
#include "llagent.h"
|
||||||
|
#include "llmutelist.h"
|
||||||
|
#include "llparticipantlist.h"
|
||||||
|
#include "llscrolllistctrl.h"
|
||||||
|
#include "llspeakers.h"
|
||||||
|
#include "llviewerwindow.h"
|
||||||
|
#include "llvoiceclient.h"
|
||||||
|
#include "llworld.h" // Edit: For ghost detection
|
||||||
|
// [RLVa:KB]
|
||||||
|
#include "rlvhandler.h"
|
||||||
|
// [/RLVa:KB]
|
||||||
|
|
||||||
|
LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
|
||||||
|
bool show_text_chatters) :
|
||||||
|
mSpeakerMgr(data_source),
|
||||||
|
mAvatarList(NULL),
|
||||||
|
mShowTextChatters(show_text_chatters),
|
||||||
|
mValidateSpeakerCallback(NULL)
|
||||||
|
{
|
||||||
|
setMouseOpaque(false);
|
||||||
|
|
||||||
|
/* Singu TODO: Avaline?
|
||||||
|
mAvalineUpdater = new LLAvalineUpdater(boost::bind(&LLParticipantList::onAvalineCallerFound, this, _1),
|
||||||
|
boost::bind(&LLParticipantList::onAvalineCallerRemoved, this, _1));*/
|
||||||
|
|
||||||
|
mSpeakerAddListener = new SpeakerAddListener(*this);
|
||||||
|
mSpeakerRemoveListener = new SpeakerRemoveListener(*this);
|
||||||
|
mSpeakerClearListener = new SpeakerClearListener(*this);
|
||||||
|
//mSpeakerModeratorListener = new SpeakerModeratorUpdateListener(*this);
|
||||||
|
mSpeakerMuteListener = new SpeakerMuteListener(*this);
|
||||||
|
|
||||||
|
mSpeakerMgr->addListener(mSpeakerAddListener, "add");
|
||||||
|
mSpeakerMgr->addListener(mSpeakerRemoveListener, "remove");
|
||||||
|
mSpeakerMgr->addListener(mSpeakerClearListener, "clear");
|
||||||
|
//mSpeakerMgr->addListener(mSpeakerModeratorListener, "update_moderator");
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL LLParticipantList::postBuild()
|
||||||
|
{
|
||||||
|
mAvatarList = getChild<LLScrollListCtrl>("speakers_list");
|
||||||
|
|
||||||
|
mAvatarList->sortByColumn(gSavedSettings.getString("FloaterActiveSpeakersSortColumn"), gSavedSettings.getBOOL("FloaterActiveSpeakersSortAscending"));
|
||||||
|
mAvatarList->setDoubleClickCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this));
|
||||||
|
mAvatarList->setCommitOnSelectionChange(true);
|
||||||
|
mAvatarList->setCommitCallback(boost::bind(&LLParticipantList::handleSpeakerSelect, this));
|
||||||
|
mAvatarList->setSortChangedCallback(boost::bind(&LLParticipantList::onSortChanged, this));
|
||||||
|
|
||||||
|
if (LLUICtrl* ctrl = findChild<LLUICtrl>("mute_text_btn"))
|
||||||
|
ctrl->setCommitCallback(boost::bind(&LLParticipantList::toggleMuteText, this));
|
||||||
|
if (LLUICtrl* ctrl = findChild<LLUICtrl>("mute_btn"))
|
||||||
|
ctrl->setCommitCallback(boost::bind(&LLParticipantList::toggleMuteVoice, this));
|
||||||
|
if (LLUICtrl* ctrl = findChild<LLUICtrl>("speaker_volume"))
|
||||||
|
ctrl->setCommitCallback(boost::bind(&LLParticipantList::onVolumeChange, this, _2));
|
||||||
|
if (LLUICtrl* ctrl = findChild<LLUICtrl>("profile_btn"))
|
||||||
|
ctrl->setCommitCallback(boost::bind(&LLParticipantList::onClickProfile, this));
|
||||||
|
if (LLUICtrl* ctrl = findChild<LLUICtrl>("moderator_allow_voice"))
|
||||||
|
ctrl->setCommitCallback(boost::bind(&LLParticipantList::moderateVoiceParticipant, this, _2));
|
||||||
|
if (LLUICtrl* ctrl = findChild<LLUICtrl>("moderator_allow_text"))
|
||||||
|
ctrl->setCommitCallback(boost::bind(&LLParticipantList::toggleAllowTextChat, this, _2));
|
||||||
|
if (LLUICtrl* ctrl = findChild<LLUICtrl>("moderator_mode"))
|
||||||
|
ctrl->setCommitCallback(boost::bind(&LLParticipantList::moderateVoiceAllParticipants, this, _2));
|
||||||
|
|
||||||
|
// update speaker UI
|
||||||
|
handleSpeakerSelect();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLParticipantList::~LLParticipantList()
|
||||||
|
{
|
||||||
|
/* Singu TODO?
|
||||||
|
mAvatarListDoubleClickConnection.disconnect();
|
||||||
|
mAvatarListRefreshConnection.disconnect();
|
||||||
|
mAvatarListReturnConnection.disconnect();
|
||||||
|
mAvatarListToggleIconsConnection.disconnect();
|
||||||
|
|
||||||
|
// It is possible Participant List will be re-created from LLCallFloater::onCurrentChannelChanged()
|
||||||
|
// See ticket EXT-3427
|
||||||
|
// hide menu before deleting it to stop enable and check handlers from triggering.
|
||||||
|
if(mParticipantListMenu && !LLApp::isExiting())
|
||||||
|
{
|
||||||
|
mParticipantListMenu->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mParticipantListMenu)
|
||||||
|
{
|
||||||
|
delete mParticipantListMenu;
|
||||||
|
mParticipantListMenu = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mAvatarList->setContextMenu(NULL);
|
||||||
|
mAvatarList->setComparator(NULL);
|
||||||
|
|
||||||
|
delete mAvalineUpdater;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*void LLParticipantList::setSpeakingIndicatorsVisible(BOOL visible)
|
||||||
|
{
|
||||||
|
mAvatarList->setSpeakingIndicatorsVisible(visible);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
void LLParticipantList::onAvatarListDoubleClicked()
|
||||||
|
{
|
||||||
|
LLAvatarActions::startIM(mAvatarList->getValue().asUUID());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLParticipantList::handleSpeakerSelect()
|
||||||
|
{
|
||||||
|
const LLUUID& speaker_id = mAvatarList->getValue().asUUID();
|
||||||
|
LLPointer<LLSpeaker> selected_speakerp = mSpeakerMgr->findSpeaker(speaker_id);
|
||||||
|
if (speaker_id.isNull() || selected_speakerp.isNull())
|
||||||
|
{
|
||||||
|
// Disable normal controls
|
||||||
|
if (LLView* view = findChild<LLView>("mute_btn"))
|
||||||
|
view->setEnabled(false);
|
||||||
|
if (LLView* view = findChild<LLView>("mute_text_btn"))
|
||||||
|
view->setEnabled(false);
|
||||||
|
if (LLView* view = findChild<LLView>("speaker_volume"))
|
||||||
|
view->setEnabled(false);
|
||||||
|
// Hide moderator controls
|
||||||
|
if (LLView* view = findChild<LLView>("moderation_mode_panel"))
|
||||||
|
view->setVisible(false);
|
||||||
|
if (LLView* view = findChild<LLView>("moderator_controls"))
|
||||||
|
view->setVisible(false);
|
||||||
|
// Clear the name
|
||||||
|
if (LLUICtrl* ctrl = findChild<LLUICtrl>("resident_name"))
|
||||||
|
ctrl->setValue(LLStringUtil::null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mSpeakerMuteListener->clearDispatchers();
|
||||||
|
|
||||||
|
bool valid_speaker = selected_speakerp->mType == LLSpeaker::SPEAKER_AGENT || selected_speakerp->mType == LLSpeaker::SPEAKER_EXTERNAL;
|
||||||
|
bool can_mute = valid_speaker && LLAvatarActions::canBlock(speaker_id);
|
||||||
|
bool voice_enabled = valid_speaker && LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->getVoiceEnabled(speaker_id);
|
||||||
|
// since setting these values is delayed by a round trip to the Vivox servers
|
||||||
|
// update them only when selecting a new speaker or
|
||||||
|
// asynchronously when an update arrives
|
||||||
|
if (LLUICtrl* ctrl = findChild<LLUICtrl>("moderator_allow_voice"))
|
||||||
|
{
|
||||||
|
ctrl->setEnabled(voice_enabled);
|
||||||
|
ctrl->setValue(!selected_speakerp->mModeratorMutedVoice);
|
||||||
|
}
|
||||||
|
if (LLUICtrl* ctrl = findChild<LLUICtrl>("moderator_allow_text"))
|
||||||
|
{
|
||||||
|
ctrl->setEnabled(true);
|
||||||
|
ctrl->setValue(!selected_speakerp->mModeratorMutedText);
|
||||||
|
}
|
||||||
|
if (LLView* view = findChild<LLView>("moderator_controls_label"))
|
||||||
|
{
|
||||||
|
view->setEnabled(true);
|
||||||
|
}
|
||||||
|
// update UI for selected participant
|
||||||
|
if (LLUICtrl* ctrl = findChild<LLUICtrl>("mute_btn"))
|
||||||
|
{
|
||||||
|
ctrl->setValue(LLAvatarActions::isVoiceMuted(speaker_id));
|
||||||
|
ctrl->setEnabled(can_mute && voice_enabled);
|
||||||
|
}
|
||||||
|
if (LLUICtrl* ctrl = findChild<LLUICtrl>("mute_text_btn"))
|
||||||
|
{
|
||||||
|
ctrl->setValue(LLAvatarActions::isBlocked(speaker_id));
|
||||||
|
ctrl->setEnabled(can_mute);
|
||||||
|
}
|
||||||
|
if (LLUICtrl* ctrl = findChild<LLUICtrl>("speaker_volume"))
|
||||||
|
{
|
||||||
|
// Singu Note: Allow modifying own voice volume during a voice session (Which is valued at half of what it should be)
|
||||||
|
ctrl->setValue(gAgentID == speaker_id ? gSavedSettings.getF32("AudioLevelMic")/2 : LLVoiceClient::getInstance()->getUserVolume(speaker_id));
|
||||||
|
ctrl->setEnabled(valid_speaker && voice_enabled);
|
||||||
|
}
|
||||||
|
if (LLView* view = findChild<LLView>("profile_btn"))
|
||||||
|
{
|
||||||
|
view->setEnabled(selected_speakerp->mType != LLSpeaker::SPEAKER_EXTERNAL);
|
||||||
|
}
|
||||||
|
// show selected user name in large font
|
||||||
|
if (LLUICtrl* ctrl = findChild<LLUICtrl>("resident_name"))
|
||||||
|
{
|
||||||
|
ctrl->setValue(selected_speakerp->mDisplayName);
|
||||||
|
}
|
||||||
|
selected_speakerp->addListener(mSpeakerMuteListener);
|
||||||
|
|
||||||
|
//update moderator capabilities
|
||||||
|
LLPointer<LLSpeaker> self_speakerp = mSpeakerMgr->findSpeaker(gAgentID);
|
||||||
|
if (self_speakerp.isNull()) return;
|
||||||
|
|
||||||
|
if (LLView* view = findChild<LLView>("moderation_mode_panel"))
|
||||||
|
{
|
||||||
|
view->setVisible(self_speakerp->mIsModerator && mSpeakerMgr->isVoiceActive());
|
||||||
|
}
|
||||||
|
if (LLView* view = findChild<LLView>("moderator_controls"))
|
||||||
|
{
|
||||||
|
view->setVisible(self_speakerp->mIsModerator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLParticipantList::refreshSpeakers()
|
||||||
|
{
|
||||||
|
// store off current selection and scroll state to preserve across list rebuilds
|
||||||
|
const S32 scroll_pos = mAvatarList->getScrollInterface()->getScrollPos();
|
||||||
|
|
||||||
|
// decide whether it's ok to resort the list then update the speaker manager appropriately.
|
||||||
|
// rapid resorting by activity makes it hard to interact with speakers in the list
|
||||||
|
// so we freeze the sorting while the user appears to be interacting with the control.
|
||||||
|
// we assume this is the case whenever the mouse pointer is within the active speaker
|
||||||
|
// panel and hasn't been motionless for more than a few seconds. see DEV-6655 -MG
|
||||||
|
LLRect screen_rect;
|
||||||
|
localRectToScreen(getLocalRect(), &screen_rect);
|
||||||
|
mSpeakerMgr->update(!(screen_rect.pointInRect(gViewerWindow->getCurrentMouseX(), gViewerWindow->getCurrentMouseY()) && gMouseIdleTimer.getElapsedTimeF32() < 5.f));
|
||||||
|
|
||||||
|
std::vector<LLScrollListItem*> items = mAvatarList->getAllData();
|
||||||
|
for (std::vector<LLScrollListItem*>::iterator item_it = items.begin(); item_it != items.end(); ++item_it)
|
||||||
|
{
|
||||||
|
LLScrollListItem* itemp = (*item_it);
|
||||||
|
LLPointer<LLSpeaker> speakerp = mSpeakerMgr->findSpeaker(itemp->getUUID());
|
||||||
|
if (speakerp.isNull()) continue;
|
||||||
|
|
||||||
|
if (LLScrollListCell* icon_cell = itemp->getColumn(0))
|
||||||
|
{
|
||||||
|
if (speakerp->mStatus == LLSpeaker::STATUS_MUTED)
|
||||||
|
{
|
||||||
|
icon_cell->setValue("mute_icon.tga");
|
||||||
|
static const LLCachedControl<LLColor4> sAscentMutedColor(gColors, "AscentMutedColor");
|
||||||
|
icon_cell->setColor(speakerp->mModeratorMutedVoice ? /*LLColor4::grey*/sAscentMutedColor : LLColor4(1.f, 71.f / 255.f, 71.f / 255.f, 1.f));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(llmin(2, llfloor((speakerp->mSpeechVolume / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 3.f)))
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
icon_cell->setValue("icn_active-speakers-dot-lvl0.tga");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
icon_cell->setValue("icn_active-speakers-dot-lvl1.tga");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
icon_cell->setValue("icn_active-speakers-dot-lvl2.tga");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// non voice speakers have hidden icons, render as transparent
|
||||||
|
icon_cell->setColor(speakerp->mStatus > LLSpeaker::STATUS_VOICE_ACTIVE ? LLColor4::transparent : speakerp->mDotColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// update name column
|
||||||
|
if (LLScrollListCell* name_cell = itemp->getColumn(1))
|
||||||
|
{
|
||||||
|
if (speakerp->mStatus == LLSpeaker::STATUS_NOT_IN_CHANNEL)
|
||||||
|
{
|
||||||
|
// draw inactive speakers in different color
|
||||||
|
static const LLCachedControl<LLColor4> sSpeakersInactive(gColors, "SpeakersInactive");
|
||||||
|
name_cell->setColor(sSpeakersInactive);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// <edit>
|
||||||
|
bool found = mShowTextChatters || speakerp->mID == gAgentID;
|
||||||
|
const LLWorld::region_list_t& regions = LLWorld::getInstance()->getRegionList();
|
||||||
|
for (LLWorld::region_list_t::const_iterator iter = regions.begin(); !found && iter != regions.end(); ++iter)
|
||||||
|
{
|
||||||
|
// Are they in this sim?
|
||||||
|
if (const LLViewerRegion* regionp = *iter)
|
||||||
|
if (regionp->mMapAvatarIDs.find(speakerp->mID) != -1)
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
static const LLCachedControl<LLColor4> sSpeakersGhost(gColors, "SpeakersGhost");
|
||||||
|
name_cell->setColor(sSpeakersGhost);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// </edit>
|
||||||
|
{
|
||||||
|
static const LLCachedControl<LLColor4> sDefaultListText(gColors, "DefaultListText");
|
||||||
|
name_cell->setColor(sDefaultListText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string speaker_name = speakerp->mDisplayName.empty() ? LLCacheName::getDefaultName() : speakerp->mDisplayName;
|
||||||
|
if (speakerp->mIsModerator)
|
||||||
|
speaker_name += " " + getString("moderator_label");
|
||||||
|
name_cell->setValue(speaker_name);
|
||||||
|
static_cast<LLScrollListText*>(name_cell)->setFontStyle(speakerp->mIsModerator ? LLFontGL::BOLD : LLFontGL::NORMAL);
|
||||||
|
}
|
||||||
|
// update speaking order column
|
||||||
|
if (LLScrollListCell* speaking_status_cell = itemp->getColumn(2))
|
||||||
|
{
|
||||||
|
// since we are forced to sort by text, encode sort order as string
|
||||||
|
// print speaking ordinal in a text-sorting friendly manner
|
||||||
|
speaking_status_cell->setValue(llformat("%010d", speakerp->mSortIndex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we potentially modified the sort order by touching the list items
|
||||||
|
mAvatarList->setNeedsSort();
|
||||||
|
|
||||||
|
// keep scroll value stable
|
||||||
|
mAvatarList->getScrollInterface()->setScrollPos(scroll_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLParticipantList::setValidateSpeakerCallback(validate_speaker_callback_t cb)
|
||||||
|
{
|
||||||
|
mValidateSpeakerCallback = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLParticipantList::onAddItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
|
||||||
|
{
|
||||||
|
LLUUID uu_id = event->getValue().asUUID();
|
||||||
|
|
||||||
|
if (mValidateSpeakerCallback && !mValidateSpeakerCallback(uu_id))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
addAvatarIDExceptAgent(uu_id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLParticipantList::onRemoveItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
|
||||||
|
{
|
||||||
|
const S32 pos = mAvatarList->getItemIndex(event->getValue().asUUID());
|
||||||
|
if (pos != -1)
|
||||||
|
{
|
||||||
|
mAvatarList->deleteSingleItem(pos);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLParticipantList::onClearListEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
|
||||||
|
{
|
||||||
|
mAvatarList->clearRows();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLParticipantList::onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
|
||||||
|
{
|
||||||
|
LLPointer<LLSpeaker> speakerp = (LLSpeaker*)event->getSource();
|
||||||
|
if (speakerp.isNull()) return false;
|
||||||
|
|
||||||
|
// update UI on confirmation of moderator mutes
|
||||||
|
if (event->getValue().asString() == "voice")
|
||||||
|
{
|
||||||
|
childSetValue("moderator_allow_voice", !speakerp->mModeratorMutedVoice);
|
||||||
|
}
|
||||||
|
else if (event->getValue().asString() == "text")
|
||||||
|
{
|
||||||
|
childSetValue("moderator_allow_text", !speakerp->mModeratorMutedText);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
|
||||||
|
{
|
||||||
|
//if (mExcludeAgent && gAgent.getID() == avatar_id) return;
|
||||||
|
if (mAvatarList->getItemIndex(avatar_id) != -1) return;
|
||||||
|
|
||||||
|
/* Singu TODO: Avaline?
|
||||||
|
bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(avatar_id);
|
||||||
|
|
||||||
|
if (is_avatar)
|
||||||
|
{
|
||||||
|
mAvatarList->getIDs().push_back(avatar_id);
|
||||||
|
mAvatarList->setDirty();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::string display_name = LLVoiceClient::getInstance()->getDisplayName(avatar_id);
|
||||||
|
mAvatarList->addAvalineItem(avatar_id, mSpeakerMgr->getSessionID(), display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name);
|
||||||
|
mAvalineUpdater->watchAvalineCaller(avatar_id);
|
||||||
|
}*/
|
||||||
|
adjustParticipant(avatar_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLParticipantList::adjustParticipant(const LLUUID& speaker_id)
|
||||||
|
{
|
||||||
|
LLPointer<LLSpeaker> speakerp = mSpeakerMgr->findSpeaker(speaker_id);
|
||||||
|
if (speakerp.isNull()) return;
|
||||||
|
|
||||||
|
LLSD row;
|
||||||
|
row["id"] = speaker_id;
|
||||||
|
LLSD& columns = row["columns"];
|
||||||
|
columns[0]["column"] = "icon_speaking_status";
|
||||||
|
columns[0]["type"] = "icon";
|
||||||
|
columns[0]["value"] = "icn_active-speakers-dot-lvl0.tga";
|
||||||
|
|
||||||
|
const std::string& display_name = LLVoiceClient::getInstance()->getDisplayName(speaker_id);
|
||||||
|
columns[1]["column"] = "speaker_name";
|
||||||
|
columns[1]["type"] = "text";
|
||||||
|
columns[1]["value"] = display_name.empty() ? LLCacheName::getDefaultName() : display_name;
|
||||||
|
|
||||||
|
columns[2]["column"] = "speaking_status";
|
||||||
|
columns[2]["type"] = "text";
|
||||||
|
columns[2]["value"] = llformat("%010d", speakerp->mSortIndex); // print speaking ordinal in a text-sorting friendly manner
|
||||||
|
mAvatarList->addElement(row);
|
||||||
|
|
||||||
|
// add listener to process moderation changes
|
||||||
|
speakerp->addListener(mSpeakerMuteListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// LLParticipantList::SpeakerAddListener
|
||||||
|
//
|
||||||
|
bool LLParticipantList::SpeakerAddListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* We need to filter speaking objects. These objects shouldn't appear in the list
|
||||||
|
* @see LLFloaterChat::addChat() in llviewermessage.cpp to get detailed call hierarchy
|
||||||
|
*/
|
||||||
|
const LLUUID& speaker_id = event->getValue().asUUID();
|
||||||
|
LLPointer<LLSpeaker> speaker = mParent.mSpeakerMgr->findSpeaker(speaker_id);
|
||||||
|
if(speaker.isNull() || speaker->mType == LLSpeaker::SPEAKER_OBJECT)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return mParent.onAddItemEvent(event, userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// LLParticipantList::SpeakerRemoveListener
|
||||||
|
//
|
||||||
|
bool LLParticipantList::SpeakerRemoveListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
|
||||||
|
{
|
||||||
|
return mParent.onRemoveItemEvent(event, userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// LLParticipantList::SpeakerClearListener
|
||||||
|
//
|
||||||
|
bool LLParticipantList::SpeakerClearListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
|
||||||
|
{
|
||||||
|
return mParent.onClearListEvent(event, userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// LLParticipantList::SpeakerMuteListener
|
||||||
|
//
|
||||||
|
bool LLParticipantList::SpeakerMuteListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
|
||||||
|
{
|
||||||
|
return mParent.onSpeakerMuteEvent(event, userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Singu Note: The following functions are actually of the LLParticipantListMenu class, but we haven't married lists with menus yet.
|
||||||
|
void LLParticipantList::toggleAllowTextChat(const LLSD& userdata)
|
||||||
|
{
|
||||||
|
if (!gAgent.getRegion()) return;
|
||||||
|
LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(mSpeakerMgr);
|
||||||
|
if (mgr)
|
||||||
|
{
|
||||||
|
const LLUUID speaker_id = mAvatarList->getValue();
|
||||||
|
mgr->toggleAllowTextChat(speaker_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLParticipantList::toggleMute(const LLSD& userdata, U32 flags)
|
||||||
|
{
|
||||||
|
const LLUUID speaker_id = userdata.asUUID(); //mUUIDs.front();
|
||||||
|
BOOL is_muted = LLMuteList::getInstance()->isMuted(speaker_id, flags);
|
||||||
|
std::string name;
|
||||||
|
|
||||||
|
//fill in name using voice client's copy of name cache
|
||||||
|
LLPointer<LLSpeaker> speakerp = mSpeakerMgr->findSpeaker(speaker_id);
|
||||||
|
if (speakerp.isNull())
|
||||||
|
{
|
||||||
|
LL_WARNS("Speakers") << "Speaker " << speaker_id << " not found" << llendl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = speakerp->mDisplayName;
|
||||||
|
|
||||||
|
LLMute::EType mute_type;
|
||||||
|
switch (speakerp->mType)
|
||||||
|
{
|
||||||
|
case LLSpeaker::SPEAKER_AGENT:
|
||||||
|
mute_type = LLMute::AGENT;
|
||||||
|
break;
|
||||||
|
case LLSpeaker::SPEAKER_OBJECT:
|
||||||
|
mute_type = LLMute::OBJECT;
|
||||||
|
break;
|
||||||
|
case LLSpeaker::SPEAKER_EXTERNAL:
|
||||||
|
default:
|
||||||
|
mute_type = LLMute::EXTERNAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
LLMute mute(speaker_id, name, mute_type);
|
||||||
|
|
||||||
|
if (!is_muted)
|
||||||
|
{
|
||||||
|
LLMuteList::getInstance()->add(mute, flags);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LLMuteList::getInstance()->remove(mute, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLParticipantList::toggleMuteText()
|
||||||
|
{
|
||||||
|
toggleMute(mAvatarList->getValue(), LLMute::flagTextChat);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLParticipantList::toggleMuteVoice()
|
||||||
|
{
|
||||||
|
toggleMute(mAvatarList->getValue(), LLMute::flagVoiceChat);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLParticipantList::moderateVoiceParticipant(const LLSD& param)
|
||||||
|
{
|
||||||
|
if (!gAgent.getRegion()) return;
|
||||||
|
LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(mSpeakerMgr);
|
||||||
|
if (mgr)
|
||||||
|
{
|
||||||
|
mgr->moderateVoiceParticipant(mAvatarList->getValue(), param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLParticipantList::moderateVoiceAllParticipants(const LLSD& param)
|
||||||
|
{
|
||||||
|
if (!gAgent.getRegion()) return;
|
||||||
|
// Singu Note: moderateVoiceAllParticipants ends up flipping the boolean passed to it before the actual post
|
||||||
|
if (LLIMSpeakerMgr* speaker_manager = dynamic_cast<LLIMSpeakerMgr*>(mSpeakerMgr))
|
||||||
|
{
|
||||||
|
if (param.asString() == "unmoderated")
|
||||||
|
{
|
||||||
|
speaker_manager->moderateVoiceAllParticipants(true);
|
||||||
|
}
|
||||||
|
else if (param.asString() == "moderated")
|
||||||
|
{
|
||||||
|
speaker_manager->moderateVoiceAllParticipants(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Singu Note: The following callbacks are not found upstream
|
||||||
|
void LLParticipantList::onVolumeChange(const LLSD& param)
|
||||||
|
{
|
||||||
|
// Singu Note: Allow modifying own voice volume during a voice session (Which is valued at half of what it should be)
|
||||||
|
const LLUUID& speaker_id = mAvatarList->getValue().asUUID();
|
||||||
|
if (gAgentID == speaker_id)
|
||||||
|
{
|
||||||
|
gSavedSettings.setF32("AudioLevelMic", param.asFloat()*2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LLVoiceClient::getInstance()->setUserVolume(speaker_id, param.asFloat());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLParticipantList::onClickProfile()
|
||||||
|
{
|
||||||
|
// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-1.0.0g
|
||||||
|
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) return;
|
||||||
|
// [/RLVa:KB]
|
||||||
|
LLAvatarActions::showProfile(mAvatarList->getValue().asUUID());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLParticipantList::onSortChanged()
|
||||||
|
{
|
||||||
|
gSavedSettings.setString("FloaterActiveSpeakersSortColumn", mAvatarList->getSortColumnName());
|
||||||
|
gSavedSettings.setBOOL("FloaterActiveSpeakersSortAscending", mAvatarList->getSortAscending());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLParticipantList::setVoiceModerationCtrlMode(const bool& moderated_voice)
|
||||||
|
{
|
||||||
|
if (LLUICtrl* voice_moderation_ctrl = findChild<LLUICtrl>("moderation_mode"))
|
||||||
|
{
|
||||||
|
voice_moderation_ctrl->setValue(moderated_voice ? "moderated" : "unmoderated");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
210
indra/newview/llparticipantlist.h
Normal file
210
indra/newview/llparticipantlist.h
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
/**
|
||||||
|
* @file llparticipantlist.h
|
||||||
|
* @brief LLParticipantList intended to update view(LLAvatarList) according to incoming messages
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
|
||||||
|
* Second Life Viewer Source Code
|
||||||
|
* Copyright (C) 2010, Linden Research, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation;
|
||||||
|
* version 2.1 of the License only.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||||
|
* $/LicenseInfo$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LL_PARTICIPANTLIST_H
|
||||||
|
#define LL_PARTICIPANTLIST_H
|
||||||
|
|
||||||
|
#include "llpanel.h"
|
||||||
|
|
||||||
|
class LLSpeakerMgr;
|
||||||
|
class LLScrollListCtrl;
|
||||||
|
class LLUICtrl;
|
||||||
|
|
||||||
|
class LLParticipantList : public LLPanel
|
||||||
|
{
|
||||||
|
LOG_CLASS(LLParticipantList);
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef boost::function<bool (const LLUUID& speaker_id)> validate_speaker_callback_t;
|
||||||
|
|
||||||
|
LLParticipantList(LLSpeakerMgr* data_source, bool show_text_chatters);
|
||||||
|
/*virtual*/ BOOL postBuild();
|
||||||
|
~LLParticipantList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds specified avatar ID to the existing list if it is not Agent's ID
|
||||||
|
*
|
||||||
|
* @param[in] avatar_id - Avatar UUID to be added into the list
|
||||||
|
*/
|
||||||
|
void addAvatarIDExceptAgent(const LLUUID& avatar_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refreshes the participant list.
|
||||||
|
*/
|
||||||
|
void refreshSpeakers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a callback to be called before adding a speaker. Invalid speakers will not be added.
|
||||||
|
*
|
||||||
|
* If the callback is unset all speakers are considered as valid.
|
||||||
|
*
|
||||||
|
* @see onAddItemEvent()
|
||||||
|
*/
|
||||||
|
void setValidateSpeakerCallback(validate_speaker_callback_t cb);
|
||||||
|
|
||||||
|
void setVoiceModerationCtrlMode(const bool& moderated_voice);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* LLSpeakerMgr event handlers
|
||||||
|
*/
|
||||||
|
bool onAddItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
|
||||||
|
bool onRemoveItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
|
||||||
|
bool onClearListEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
|
||||||
|
//bool onModeratorUpdateEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
|
||||||
|
bool onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of listeners implementing LLOldEvents::LLSimpleListener.
|
||||||
|
* There is no way to handle all the events in one listener as LLSpeakerMgr registers
|
||||||
|
* listeners in such a way that one listener can handle only one type of event
|
||||||
|
**/
|
||||||
|
class BaseSpeakerListener : public LLOldEvents::LLSimpleListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BaseSpeakerListener(LLParticipantList& parent) : mParent(parent) {}
|
||||||
|
protected:
|
||||||
|
LLParticipantList& mParent;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SpeakerAddListener : public BaseSpeakerListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SpeakerAddListener(LLParticipantList& parent) : BaseSpeakerListener(parent) {}
|
||||||
|
/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SpeakerRemoveListener : public BaseSpeakerListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SpeakerRemoveListener(LLParticipantList& parent) : BaseSpeakerListener(parent) {}
|
||||||
|
/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SpeakerClearListener : public BaseSpeakerListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SpeakerClearListener(LLParticipantList& parent) : BaseSpeakerListener(parent) {}
|
||||||
|
/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*class SpeakerModeratorUpdateListener : public BaseSpeakerListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SpeakerModeratorUpdateListener(LLParticipantList& parent) : BaseSpeakerListener(parent) {}
|
||||||
|
*virtual* bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
|
||||||
|
};*/
|
||||||
|
|
||||||
|
class SpeakerMuteListener : public BaseSpeakerListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SpeakerMuteListener(LLParticipantList& parent) : BaseSpeakerListener(parent) {}
|
||||||
|
|
||||||
|
/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menu used in the participant list.
|
||||||
|
class LLParticipantListMenu : public LLListContextMenu
|
||||||
|
{
|
||||||
|
*/
|
||||||
|
private:
|
||||||
|
void toggleAllowTextChat(const LLSD& userdata);
|
||||||
|
void toggleMute(const LLSD& userdata, U32 flags);
|
||||||
|
void toggleMuteText();
|
||||||
|
void toggleMuteVoice();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes Voice moderation menu items.
|
||||||
|
*
|
||||||
|
* It calls either moderateVoiceParticipant() or moderateVoiceParticipant() depend on
|
||||||
|
* passed parameter.
|
||||||
|
*
|
||||||
|
* @param userdata can be "selected" or "others".
|
||||||
|
*
|
||||||
|
* @see moderateVoiceParticipant()
|
||||||
|
* @see moderateVoiceAllParticipants()
|
||||||
|
*/
|
||||||
|
void moderateVoice(const LLSD& userdata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mutes/Unmutes avatar for current group voice chat.
|
||||||
|
*
|
||||||
|
* It only marks avatar as muted for session and does not use local Agent's Block list.
|
||||||
|
* It does not mute Agent itself.
|
||||||
|
*
|
||||||
|
* @param[in] avatar_id UUID of avatar to be processed
|
||||||
|
* @param[in] unmute if true - specified avatar will be muted, otherwise - unmuted.
|
||||||
|
*
|
||||||
|
* @see moderateVoiceAllParticipants()
|
||||||
|
*/
|
||||||
|
void moderateVoiceParticipant(const LLSD& param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mutes/Unmutes all avatars for current group voice chat.
|
||||||
|
*
|
||||||
|
* It only marks avatars as muted for session and does not use local Agent's Block list.
|
||||||
|
*
|
||||||
|
* @param[in] unmute if true - avatars will be muted, otherwise - unmuted.
|
||||||
|
*
|
||||||
|
* @see moderateVoiceParticipant()
|
||||||
|
*/
|
||||||
|
void moderateVoiceAllParticipants(const LLSD& param);
|
||||||
|
|
||||||
|
//static void confirmMuteAllCallback(const LLSD& notification, const LLSD& response);
|
||||||
|
//};
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onAvatarListDoubleClicked();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjusts passed participant to work properly.
|
||||||
|
*
|
||||||
|
* Adds SpeakerMuteListener to process moderation actions.
|
||||||
|
*/
|
||||||
|
void adjustParticipant(const LLUUID& speaker_id);
|
||||||
|
|
||||||
|
// Singu Note: The following callbacks are not found upstream
|
||||||
|
void handleSpeakerSelect();
|
||||||
|
void onClickProfile();
|
||||||
|
void onSortChanged();
|
||||||
|
void onVolumeChange(const LLSD& param);
|
||||||
|
|
||||||
|
LLSpeakerMgr* mSpeakerMgr;
|
||||||
|
LLScrollListCtrl* mAvatarList;
|
||||||
|
bool mShowTextChatters;
|
||||||
|
|
||||||
|
LLPointer<SpeakerAddListener> mSpeakerAddListener;
|
||||||
|
LLPointer<SpeakerRemoveListener> mSpeakerRemoveListener;
|
||||||
|
LLPointer<SpeakerClearListener> mSpeakerClearListener;
|
||||||
|
//LLPointer<SpeakerModeratorUpdateListener> mSpeakerModeratorListener;
|
||||||
|
LLPointer<SpeakerMuteListener> mSpeakerMuteListener;
|
||||||
|
|
||||||
|
validate_speaker_callback_t mValidateSpeakerCallback;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LL_PARTICIPANTLIST_H
|
||||||
|
|
||||||
@@ -419,7 +419,7 @@ void LLSpeakerMgr::update(BOOL resort_ok)
|
|||||||
if(speakerp->mType == LLSpeaker::SPEAKER_EXTERNAL)
|
if(speakerp->mType == LLSpeaker::SPEAKER_EXTERNAL)
|
||||||
{
|
{
|
||||||
// external speakers should be timed out when they leave the voice channel (since they only exist via SLVoice)
|
// external speakers should be timed out when they leave the voice channel (since they only exist via SLVoice)
|
||||||
speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL;
|
setSpeakerNotInChannel(speakerp); // Singu Note: Don't just flag, call the flagging function and get them on the removal timer!
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -903,7 +903,7 @@ void LLActiveSpeakerMgr::updateSpeakerList()
|
|||||||
if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY)
|
if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY)
|
||||||
{
|
{
|
||||||
// automatically flag text only speakers for removal
|
// automatically flag text only speakers for removal
|
||||||
speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL;
|
setSpeakerNotInChannel(speakerp); // Singu Note: Don't just flag, call the flagging function and get them on the removal timer!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,6 @@
|
|||||||
|
|
||||||
// linden library includes
|
// linden library includes
|
||||||
#include "llaudioengine.h" // mute on minimize
|
#include "llaudioengine.h" // mute on minimize
|
||||||
#include "indra_constants.h"
|
|
||||||
#include "llassetstorage.h"
|
#include "llassetstorage.h"
|
||||||
#include "llfontgl.h"
|
#include "llfontgl.h"
|
||||||
#include "llmousehandler.h"
|
#include "llmousehandler.h"
|
||||||
@@ -77,12 +76,9 @@
|
|||||||
#include "raytrace.h"
|
#include "raytrace.h"
|
||||||
|
|
||||||
// newview includes
|
// newview includes
|
||||||
#include "llagent.h"
|
|
||||||
#include "llbox.h"
|
#include "llbox.h"
|
||||||
#include "llchatbar.h"
|
#include "llchatbar.h"
|
||||||
#include "llconsole.h"
|
#include "llconsole.h"
|
||||||
#include "llviewercontrol.h"
|
|
||||||
#include "llcylinder.h"
|
|
||||||
#include "lldebugview.h"
|
#include "lldebugview.h"
|
||||||
#include "lldir.h"
|
#include "lldir.h"
|
||||||
#include "lldrawable.h"
|
#include "lldrawable.h"
|
||||||
@@ -93,20 +89,11 @@
|
|||||||
#include "llface.h"
|
#include "llface.h"
|
||||||
#include "llfeaturemanager.h"
|
#include "llfeaturemanager.h"
|
||||||
#include "statemachine/aifilepicker.h"
|
#include "statemachine/aifilepicker.h"
|
||||||
#include "llfloater.h"
|
|
||||||
#include "llfloateractivespeakers.h"
|
|
||||||
#include "llfloaterbuildoptions.h"
|
|
||||||
#include "llfloaterbuyland.h"
|
|
||||||
#include "llfloatercamera.h"
|
#include "llfloatercamera.h"
|
||||||
#include "llfloaterchat.h"
|
#include "llfloaterchat.h"
|
||||||
#include "llfloaterchatterbox.h"
|
#include "llfloaterchatterbox.h"
|
||||||
#include "llfloatercustomize.h"
|
#include "llfloatercustomize.h"
|
||||||
#include "llfloatereditui.h" // HACK JAMESDEBUG for ui editor
|
#include "llfloatereditui.h" // HACK JAMESDEBUG for ui editor
|
||||||
#include "llfloaterland.h"
|
|
||||||
#include "llfloaterinspect.h"
|
|
||||||
#include "llfloaterinventory.h"
|
|
||||||
#include "llfloaternamedesc.h"
|
|
||||||
#include "llfloaterpreference.h"
|
|
||||||
#include "llfloatersnapshot.h"
|
#include "llfloatersnapshot.h"
|
||||||
#include "llfloaterteleporthistory.h"
|
#include "llfloaterteleporthistory.h"
|
||||||
#include "llfloatertools.h"
|
#include "llfloatertools.h"
|
||||||
@@ -196,7 +183,6 @@
|
|||||||
#include "llnotifications.h"
|
#include "llnotifications.h"
|
||||||
#include "llnotificationsutil.h"
|
#include "llnotificationsutil.h"
|
||||||
|
|
||||||
#include "llfloatertest.h" // HACK!
|
|
||||||
#include "llfloaternotificationsconsole.h"
|
#include "llfloaternotificationsconsole.h"
|
||||||
|
|
||||||
// [RLVa:KB]
|
// [RLVa:KB]
|
||||||
|
|||||||
Reference in New Issue
Block a user