Updated avatar radar. Focusprev/focusnext now obey the order of the actual displayed avatar list. Cleaned up some commit callbacks.

This commit is contained in:
Shyotl
2012-12-06 17:16:44 -06:00
parent 26191dd274
commit e750c598be
4 changed files with 277 additions and 408 deletions

View File

@@ -2803,18 +2803,18 @@ void LLAgentCamera::lookAtLastChat()
} }
//Pulled implementation out of lookAtLastChat and adapted to work for for general objects //Pulled implementation out of lookAtLastChat and adapted to work for for general objects
void LLAgentCamera::lookAtObject(const LLUUID &object_id, bool self) bool LLAgentCamera::lookAtObject(const LLUUID &object_id, bool self)
{ {
// Block if camera is animating or not in normal third person camera mode // Block if camera is animating or not in normal third person camera mode
if (mCameraAnimating || !cameraThirdPerson()) if (mCameraAnimating || !cameraThirdPerson())
{ {
return; return false;
} }
LLViewerObject *chatter = gObjectList.findObject(object_id); LLViewerObject *chatter = gObjectList.findObject(object_id);
if (!chatter) if (!chatter)
{ {
return; return false;
} }
LLVector3 delta_pos; LLVector3 delta_pos;
@@ -2845,7 +2845,7 @@ void LLAgentCamera::lookAtObject(const LLUUID &object_id, bool self)
new_camera_pos += left * 0.3f; new_camera_pos += left * 0.3f;
new_camera_pos += up * 0.2f; new_camera_pos += up * 0.2f;
//setFocusOnAvatar(FALSE, FALSE); setFocusOnAvatar(FALSE, FALSE);
if (chatter_av->mHeadp) if (chatter_av->mHeadp)
{ {
@@ -2863,7 +2863,6 @@ void LLAgentCamera::lookAtObject(const LLUUID &object_id, bool self)
else else
mCameraFocusOffsetTarget.setVec(radius, radius, 0.f); mCameraFocusOffsetTarget.setVec(radius, radius, 0.f);
} }
setFocusOnAvatar(FALSE, TRUE);
} }
else else
{ {
@@ -2883,17 +2882,15 @@ void LLAgentCamera::lookAtObject(const LLUUID &object_id, bool self)
new_camera_pos += left * 0.3f; new_camera_pos += left * 0.3f;
new_camera_pos += up * 0.2f; new_camera_pos += up * 0.2f;
//setFocusOnAvatar(FALSE, FALSE); setFocusOnAvatar(FALSE, FALSE);
setFocusGlobal(chatter->getPositionGlobal(), object_id); setFocusGlobal(chatter->getPositionGlobal(), object_id);
if(self) if(self)
mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal(); mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
else else
mCameraFocusOffsetTarget.setVec(radius, radius, 0.f); mCameraFocusOffsetTarget.setVec(radius, radius, 0.f);
setFocusOnAvatar(FALSE, TRUE);
} }
return true;
} }

View File

@@ -234,7 +234,7 @@ public:
BOOL setLookAt(ELookAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero); BOOL setLookAt(ELookAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero);
ELookAtType getLookAtType(); ELookAtType getLookAtType();
void lookAtLastChat(); void lookAtLastChat();
void lookAtObject(const LLUUID &object_id, bool self=true); bool lookAtObject(const LLUUID &object_id, bool self=true);
void slamLookAt(const LLVector3 &look_at); // Set the physics data void slamLookAt(const LLVector3 &look_at); // Set the physics data
BOOL setPointAt(EPointAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero); BOOL setPointAt(EPointAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero);
EPointAtType getPointAtType(); EPointAtType getPointAtType();

View File

@@ -52,7 +52,7 @@
#include <string.h> #include <string.h>
#include <map> #include <map>
#include <boost/foreach.hpp>
#include "llworld.h" #include "llworld.h"
#include "llsdutil.h" #include "llsdutil.h"
@@ -137,10 +137,11 @@ void chat_avatar_status(std::string name, LLUUID key, ERadarAlertType type, bool
} }
LLAvatarListEntry::LLAvatarListEntry(const LLUUID& id, const std::string &name, const LLVector3d &position) : LLAvatarListEntry::LLAvatarListEntry(const LLUUID& id, const std::string &name, const LLVector3d &position) :
mID(id), mName(name), mPosition(position), mDrawPosition(), mMarked(FALSE), mFocused(FALSE), mID(id), mName(name), mPosition(position), mDrawPosition(), mMarked(false), mFocused(false),
mUpdateTimer(), mFrame(gFrameCount), mInSimFrame(U32_MAX), mInDrawFrame(U32_MAX), mUpdateTimer(), mFrame(gFrameCount), mInSimFrame(U32_MAX), mInDrawFrame(U32_MAX),
mInChatFrame(U32_MAX), mInShoutFrame(U32_MAX), mInChatFrame(U32_MAX), mInShoutFrame(U32_MAX),
mActivityType(ACTIVITY_NEW), mActivityTimer() mActivityType(ACTIVITY_NEW), mActivityTimer(),
mIsInList(false)
{ {
} }
@@ -220,12 +221,12 @@ bool LLAvatarListEntry::getAlive()
return ((current - mFrame) <= 2); return ((current - mFrame) <= 2);
} }
F32 LLAvatarListEntry::getEntryAgeSeconds() F32 LLAvatarListEntry::getEntryAgeSeconds() const
{ {
return mUpdateTimer.getElapsedTimeF32(); return mUpdateTimer.getElapsedTimeF32();
} }
BOOL LLAvatarListEntry::isDead() bool LLAvatarListEntry::isDead() const
{ {
return getEntryAgeSeconds() > DEAD_KEEP_TIME; return getEntryAgeSeconds() > DEAD_KEEP_TIME;
} }
@@ -239,7 +240,7 @@ void LLAvatarListEntry::setActivity(ACTIVITY_TYPE activity)
} }
} }
LLAvatarListEntry::ACTIVITY_TYPE LLAvatarListEntry::getActivity() const LLAvatarListEntry::ACTIVITY_TYPE LLAvatarListEntry::getActivity()
{ {
if ( mActivityTimer.getElapsedTimeF32() > ACTIVITY_TIMEOUT ) if ( mActivityTimer.getElapsedTimeF32() > ACTIVITY_TIMEOUT )
{ {
@@ -250,10 +251,14 @@ LLAvatarListEntry::ACTIVITY_TYPE LLAvatarListEntry::getActivity()
return mActivityType; return mActivityType;
} }
LLFloaterAvatarList::LLFloaterAvatarList() : LLFloater(std::string("radar")) LLFloaterAvatarList::LLFloaterAvatarList() : LLFloater(std::string("radar")),
mTracking(false),
mUpdate(true),
mDirtyAvatarSorting(false),
mUpdateRate(gSavedSettings.getU32("RadarUpdateRate") * 3 + 3),
mAvatarList(NULL)
{ {
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_radar.xml"); LLUICtrlFactory::getInstance()->buildFloater(this, "floater_radar.xml");
mUpdateRate = gSavedSettings.getU32("RadarUpdateRate") * 3 + 3;
} }
LLFloaterAvatarList::~LLFloaterAvatarList() LLFloaterAvatarList::~LLFloaterAvatarList()
@@ -315,46 +320,46 @@ void LLFloaterAvatarList::onClose(bool app_quitting)
} }
} }
void cmd_profile(const LLAvatarListEntry* entry);
void cmd_toggle_mark(LLAvatarListEntry* entry);
void cmd_ar(const LLAvatarListEntry* entry);
void cmd_teleport(const LLAvatarListEntry* entry);
BOOL LLFloaterAvatarList::postBuild() BOOL LLFloaterAvatarList::postBuild()
{ {
// Default values
mTracking = FALSE;
mUpdate = TRUE;
// Set callbacks // Set callbacks
childSetAction("profile_btn", onClickProfile, this); childSetAction("profile_btn", boost::bind(&LLFloaterAvatarList::doCommand, this, &cmd_profile, false));
childSetAction("im_btn", onClickIM, this); childSetAction("im_btn", boost::bind(&LLFloaterAvatarList::onClickIM, this));
childSetAction("offer_btn", onClickTeleportOffer, this); childSetAction("offer_btn", boost::bind(&LLFloaterAvatarList::onClickTeleportOffer, this));
childSetAction("track_btn", onClickTrack, this); childSetAction("track_btn", boost::bind(&LLFloaterAvatarList::onClickTrack, this));
childSetAction("mark_btn", onClickMark, this); childSetAction("mark_btn", boost::bind(&LLFloaterAvatarList::doCommand, this, &cmd_toggle_mark, false));
childSetAction("focus_btn", onClickFocus, this); childSetAction("focus_btn", boost::bind(&LLFloaterAvatarList::onClickFocus, this));
childSetAction("prev_in_list_btn", onClickPrevInList, this); childSetAction("prev_in_list_btn", boost::bind(&LLFloaterAvatarList::focusOnPrev, this, FALSE));
childSetAction("next_in_list_btn", onClickNextInList, this); childSetAction("next_in_list_btn", boost::bind(&LLFloaterAvatarList::focusOnNext, this, FALSE));
childSetAction("prev_marked_btn", onClickPrevMarked, this); childSetAction("prev_marked_btn", boost::bind(&LLFloaterAvatarList::focusOnPrev, this, TRUE));
childSetAction("next_marked_btn", onClickNextMarked, this); childSetAction("next_marked_btn", boost::bind(&LLFloaterAvatarList::focusOnNext, this, TRUE));
childSetAction("get_key_btn", onClickGetKey, this); childSetAction("get_key_btn", boost::bind(&LLFloaterAvatarList::onClickGetKey, this));
childSetAction("freeze_btn", onClickFreeze, this); childSetAction("freeze_btn", boost::bind(&LLFloaterAvatarList::onClickFreeze, this));
childSetAction("eject_btn", onClickEject, this); childSetAction("eject_btn", boost::bind(&LLFloaterAvatarList::onClickEject, this));
childSetAction("mute_btn", onClickMute, this); childSetAction("mute_btn", boost::bind(&LLFloaterAvatarList::onClickMute, this));
childSetAction("ar_btn", onClickAR, this); childSetAction("ar_btn", boost::bind(&LLFloaterAvatarList::doCommand, this, &cmd_ar, true));
childSetAction("teleport_btn", onClickTeleport, this); childSetAction("teleport_btn", boost::bind(&LLFloaterAvatarList::doCommand, this, &cmd_teleport, true));
childSetAction("estate_eject_btn", onClickEjectFromEstate, this); childSetAction("estate_eject_btn", boost::bind(&LLFloaterAvatarList::onClickEjectFromEstate, this));
childSetAction("estate_ban_btn", onClickBanFromEstate, this); childSetAction("estate_ban_btn",boost::bind(&LLFloaterAvatarList:: onClickBanFromEstate, this));
childSetAction("send_keys_btn", onClickSendKeys, this); childSetAction("send_keys_btn", boost::bind(&LLFloaterAvatarList::sendKeys, this));
getChild<LLRadioGroup>("update_rate")->setSelectedIndex(gSavedSettings.getU32("RadarUpdateRate")); getChild<LLRadioGroup>("update_rate")->setSelectedIndex(gSavedSettings.getU32("RadarUpdateRate"));
childSetCommitCallback("update_rate", onCommitUpdateRate, this); getChild<LLRadioGroup>("update_rate")->setCommitCallback(boost::bind(&LLFloaterAvatarList::onCommitUpdateRate, this));
// Get a pointer to the scroll list from the interface // Get a pointer to the scroll list from the interface
mAvatarList = getChild<LLScrollListCtrl>("avatar_list"); mAvatarList = getChild<LLScrollListCtrl>("avatar_list");
mAvatarList->sortByColumn("distance", TRUE); mAvatarList->sortByColumn("distance", TRUE);
mAvatarList->setCommitOnSelectionChange(TRUE); mAvatarList->setCommitOnSelectionChange(TRUE);
mAvatarList->setCallbackUserData(this);
mAvatarList->setCommitCallback(boost::bind(&LLFloaterAvatarList::onSelectName,this)); mAvatarList->setCommitCallback(boost::bind(&LLFloaterAvatarList::onSelectName,this));
mAvatarList->setDoubleClickCallback(boost::bind(&LLFloaterAvatarList::onClickFocus,this)); mAvatarList->setDoubleClickCallback(boost::bind(&LLFloaterAvatarList::onClickFocus,this));
mAvatarList->setSortChangedCallback(boost::bind(&LLFloaterAvatarList::onAvatarSortingChanged,this));
refreshAvatarList(); refreshAvatarList();
gIdleCallbacks.addFunction(LLFloaterAvatarList::callbackIdle); gIdleCallbacks.addFunction(LLFloaterAvatarList::callbackIdle);
@@ -438,9 +443,9 @@ void LLFloaterAvatarList::updateAvatarList()
sorted_avatar_ids = avatar_ids; sorted_avatar_ids = avatar_ids;
std::sort(sorted_avatar_ids.begin(), sorted_avatar_ids.end()); std::sort(sorted_avatar_ids.begin(), sorted_avatar_ids.end());
for (std::vector<LLCharacter*>::const_iterator iter = LLCharacter::sInstances.begin(); iter != LLCharacter::sInstances.end(); ++iter) BOOST_FOREACH(std::vector<LLCharacter*>::value_type& iter, LLCharacter::sInstances)
{ {
LLUUID avid = (*iter)->getID(); LLUUID avid = iter->getID();
if (!std::binary_search(sorted_avatar_ids.begin(), sorted_avatar_ids.end(), avid)) if (!std::binary_search(sorted_avatar_ids.begin(), sorted_avatar_ids.end(), avid))
{ {
@@ -512,12 +517,13 @@ void LLFloaterAvatarList::updateAvatarList()
continue; continue;
} }
if (mAvatars.count(avid) > 0) LLAvatarListEntry* entry = getAvatarEntry(avid);
if (entry)
{ {
// Avatar already in list, update position // Avatar already in list, update position
F32 dist = (F32)(position - mypos).magVec(); F32 dist = (F32)(position - mypos).magVec();
mAvatars[avid].setPosition(position, (avatarp->getRegion() == gAgent.getRegion()), true, dist < 20.0, dist < 100.0); entry->setPosition(position, (avatarp->getRegion() == gAgent.getRegion()), true, dist < 20.0, dist < 100.0);
if(avatarp->isTyping())mAvatars[avid].setActivity(LLAvatarListEntry::ACTIVITY_TYPING); if(avatarp->isTyping())entry->setActivity(LLAvatarListEntry::ACTIVITY_TYPING);
} }
else else
{ {
@@ -525,7 +531,7 @@ void LLFloaterAvatarList::updateAvatarList()
LLAvatarListEntry entry(avid, name, position); LLAvatarListEntry entry(avid, name, position);
if(announce && avatarp->getRegion() == gAgent.getRegion()) if(announce && avatarp->getRegion() == gAgent.getRegion())
announce_keys.push(avid); announce_keys.push(avid);
mAvatars[avid] = entry; mAvatars.push_back(entry);
} }
} }
else else
@@ -545,18 +551,19 @@ void LLFloaterAvatarList::updateAvatarList()
continue; //prevent (Loading...) continue; //prevent (Loading...)
} }
if (mAvatars.count(avid) > 0) LLAvatarListEntry* entry = getAvatarEntry(avid);
if (entry)
{ {
// Avatar already in list, update position // Avatar already in list, update position
F32 dist = (F32)(position - mypos).magVec(); F32 dist = (F32)(position - mypos).magVec();
mAvatars[avid].setPosition(position, gAgent.getRegion()->pointInRegionGlobal(position), false, dist < 20.0, dist < 100.0); entry->setPosition(position, gAgent.getRegion()->pointInRegionGlobal(position), false, dist < 20.0, dist < 100.0);
} }
else else
{ {
LLAvatarListEntry entry(avid, name, position); LLAvatarListEntry entry(avid, name, position);
if(announce && gAgent.getRegion()->pointInRegionGlobal(position)) if(announce && gAgent.getRegion()->pointInRegionGlobal(position))
announce_keys.push(avid); announce_keys.push(avid);
mAvatars[avid] = entry; mAvatars.push_back(entry);
} }
} }
} }
@@ -618,28 +625,39 @@ void LLFloaterAvatarList::updateAvatarList()
void LLFloaterAvatarList::expireAvatarList() void LLFloaterAvatarList::expireAvatarList()
{ {
// llinfos << "radar: expiring" << llendl; // llinfos << "radar: expiring" << llendl;
std::map<LLUUID, LLAvatarListEntry>::iterator iter; for(av_list_t::iterator it = mAvatars.begin(); it != mAvatars.end();)
std::queue<LLUUID> delete_queue;
bool alive;
for (iter = mAvatars.begin(); iter != mAvatars.end(); iter++)
{ {
LLAvatarListEntry *entry = &iter->second; if(!it->isDead())
(it++)->getAlive();
alive = entry->getAlive(); else
if (entry->isDead())
{ {
//llinfos << "radar: expiring avatar " << entry->getName() << llendl; std::swap(*it,mAvatars.back());
LLUUID av_id = entry->getID(); mAvatars.pop_back();
delete_queue.push(av_id); if(!mAvatars.size())
return;
} }
} }
}
while (!delete_queue.empty()) void LLFloaterAvatarList::updateAvatarSorting()
{
if(mDirtyAvatarSorting)
{ {
mAvatars.erase(delete_queue.front()); mDirtyAvatarSorting = false;
delete_queue.pop(); if(mAvatars.size() <= 1) //Nothing to sort.
return;
const std::vector<LLScrollListItem*> list = mAvatarList->getAllData();
av_list_t::iterator insert_it = mAvatars.begin();
for(std::vector<LLScrollListItem*>::const_iterator it=list.begin();it!=list.end();++it)
{
av_list_t::iterator av_it = std::find_if(mAvatars.begin(),mAvatars.end(),LLAvatarListEntry::uuidMatch((*it)->getUUID()));
if(av_it!=mAvatars.end())
{
std::iter_swap(insert_it++,av_it);
if(insert_it+1 == mAvatars.end()) //We've ran out of elements to sort
return;
}
}
} }
} }
@@ -666,25 +684,24 @@ void LLFloaterAvatarList::refreshAvatarList()
posagent.setVec(gAgent.getPositionAgent()); posagent.setVec(gAgent.getPositionAgent());
LLVector3d simpos = mypos - posagent; LLVector3d simpos = mypos - posagent;
std::map<LLUUID, LLAvatarListEntry>::iterator iter; BOOST_FOREACH(av_list_t::value_type& entry, mAvatars)
for (iter = mAvatars.begin(); iter != mAvatars.end(); iter++)
{ {
LLSD element; LLSD element;
LLUUID av_id; LLUUID av_id;
std::string av_name; std::string av_name;
LLAvatarListEntry* entry = &iter->second;
// Skip if avatar hasn't been around // Skip if avatar hasn't been around
if (entry->isDead()) if (entry.isDead())
{ {
continue; continue;
} }
av_id = entry->getID(); entry.setInList();
av_name = entry->getName().c_str();
LLVector3d position = entry->getPosition(); av_id = entry.getID();
av_name = entry.getName().c_str();
LLVector3d position = entry.getPosition();
BOOL UnknownAltitude = false; BOOL UnknownAltitude = false;
LLVector3d delta = position - mypos; LLVector3d delta = position - mypos;
@@ -720,7 +737,7 @@ void LLFloaterAvatarList::refreshAvatarList()
element["columns"][LIST_MARK]["column"] = "marked"; element["columns"][LIST_MARK]["column"] = "marked";
element["columns"][LIST_MARK]["type"] = "text"; element["columns"][LIST_MARK]["type"] = "text";
if (entry->isMarked()) if (entry.isMarked())
{ {
element["columns"][LIST_MARK]["value"] = "X"; element["columns"][LIST_MARK]["value"] = "X";
element["columns"][LIST_MARK]["color"] = LLColor4::blue.getValue(); element["columns"][LIST_MARK]["color"] = LLColor4::blue.getValue();
@@ -734,7 +751,7 @@ void LLFloaterAvatarList::refreshAvatarList()
element["columns"][LIST_AVATAR_NAME]["column"] = "avatar_name"; element["columns"][LIST_AVATAR_NAME]["column"] = "avatar_name";
element["columns"][LIST_AVATAR_NAME]["type"] = "text"; element["columns"][LIST_AVATAR_NAME]["type"] = "text";
element["columns"][LIST_AVATAR_NAME]["value"] = av_name; element["columns"][LIST_AVATAR_NAME]["value"] = av_name;
if (entry->isFocused()) if (entry.isFocused())
{ {
element["columns"][LIST_AVATAR_NAME]["font-style"] = "BOLD"; element["columns"][LIST_AVATAR_NAME]["font-style"] = "BOLD";
} }
@@ -742,7 +759,7 @@ void LLFloaterAvatarList::refreshAvatarList()
//<edit> custom colors for certain types of avatars! //<edit> custom colors for certain types of avatars!
//Changed a bit so people can modify them in settings. And since they're colors, again it's possibly account-based. Starting to think I need a function just to determine that. - HgB //Changed a bit so people can modify them in settings. And since they're colors, again it's possibly account-based. Starting to think I need a function just to determine that. - HgB
//element["columns"][LIST_AVATAR_NAME]["color"] = gColors.getColor( "MapAvatar" ).getValue(); //element["columns"][LIST_AVATAR_NAME]["color"] = gColors.getColor( "MapAvatar" ).getValue();
LLViewerRegion* parent_estate = LLWorld::getInstance()->getRegionFromPosGlobal(entry->getPosition()); LLViewerRegion* parent_estate = LLWorld::getInstance()->getRegionFromPosGlobal(entry.getPosition());
LLUUID estate_owner = LLUUID::null; LLUUID estate_owner = LLUUID::null;
if(parent_estate && parent_estate->isAlive()) if(parent_estate && parent_estate->isAlive())
{ {
@@ -793,7 +810,7 @@ void LLFloaterAvatarList::refreshAvatarList()
if (UnknownAltitude) if (UnknownAltitude)
{ {
strcpy(temp, "?"); strcpy(temp, "?");
if (entry->isDrawn()) if (entry.isDrawn())
{ {
color = sRadarTextDrawDist; color = sRadarTextDrawDist;
} }
@@ -814,7 +831,7 @@ void LLFloaterAvatarList::refreshAvatarList()
} }
else else
{ {
if (entry->isDrawn()) if (entry.isDrawn())
{ {
color = sRadarTextDrawDist; color = sRadarTextDrawDist;
} }
@@ -872,7 +889,7 @@ void LLFloaterAvatarList::refreshAvatarList()
element["columns"][LIST_ACTIVITY]["type"] = "icon"; element["columns"][LIST_ACTIVITY]["type"] = "icon";
std::string activity_icon = ""; std::string activity_icon = "";
switch(entry->getActivity()) switch(entry.getActivity())
{ {
case LLAvatarListEntry::ACTIVITY_MOVING: case LLAvatarListEntry::ACTIVITY_MOVING:
activity_icon = "inv_item_animation.tga"; activity_icon = "inv_item_animation.tga";
@@ -947,18 +964,17 @@ void LLFloaterAvatarList::refreshAvatarList()
mAvatarList->sortItems(); mAvatarList->sortItems();
mAvatarList->selectMultiple(selected); mAvatarList->selectMultiple(selected);
mAvatarList->setScrollPos(scrollpos); mAvatarList->setScrollPos(scrollpos);
mDirtyAvatarSorting = true;
// llinfos << "radar refresh: done" << llendl; // llinfos << "radar refresh: done" << llendl;
} }
// static void LLFloaterAvatarList::onClickIM()
void LLFloaterAvatarList::onClickIM(void* userdata)
{ {
//llinfos << "LLFloaterFriends::onClickIM()" << llendl; //llinfos << "LLFloaterFriends::onClickIM()" << llendl;
LLFloaterAvatarList *self = (LLFloaterAvatarList*)userdata; LLDynamicArray<LLUUID> ids = mAvatarList->getSelectedIDs();
LLDynamicArray<LLUUID> ids = self->mAvatarList->getSelectedIDs();
if (ids.size() > 0) if (ids.size() > 0)
{ {
if (ids.size() == 1) if (ids.size() == 1)
@@ -986,42 +1002,34 @@ void LLFloaterAvatarList::onClickIM(void* userdata)
} }
} }
void LLFloaterAvatarList::onClickTeleportOffer(void* userdata) void LLFloaterAvatarList::onClickTeleportOffer()
{ {
LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; LLDynamicArray<LLUUID> ids = mAvatarList->getSelectedIDs();
LLDynamicArray<LLUUID> ids = self->mAvatarList->getSelectedIDs();
if (ids.size() > 0) if (ids.size() > 0)
{ {
handle_lure(ids); handle_lure(ids);
} }
} }
void LLFloaterAvatarList::onClickTrack(void* userdata) void LLFloaterAvatarList::onClickTrack()
{ {
LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; LLScrollListItem* item = mAvatarList->getFirstSelected();
LLScrollListItem* item = self->mAvatarList->getFirstSelected();
if (!item) return; if (!item) return;
LLUUID agent_id = item->getUUID(); LLUUID agent_id = item->getUUID();
if (self->mTracking && self->mTrackedAvatar == agent_id) { if (mTracking && mTrackedAvatar == agent_id)
{
LLTracker::stopTracking(NULL); LLTracker::stopTracking(NULL);
self->mTracking = FALSE; mTracking = FALSE;
} }
else else
{ {
self->mTracking = TRUE; mTracking = TRUE;
self->mTrackedAvatar = agent_id; mTrackedAvatar = agent_id;
// trackAvatar only works for friends allowing you to see them on map... // trackAvatar only works for friends allowing you to see them on map...
// LLTracker::trackAvatar(agent_id, self->mAvatars[agent_id].getName()); // LLTracker::trackAvatar(agent_id, self->mAvatars[agent_id].getName());
std::string name = self->mAvatars[agent_id].getName(); trackAvatar(getAvatarEntry(mTrackedAvatar));
if (!self->mUpdate)
{
name += "\n(last known position)";
}
LLTracker::trackLocation(self->mAvatars[agent_id].getPosition(), name, name);
} }
} }
@@ -1031,15 +1039,12 @@ void LLFloaterAvatarList::refreshTracker()
if (LLTracker::isTracking(NULL)) if (LLTracker::isTracking(NULL))
{ {
LLVector3d pos = mAvatars[mTrackedAvatar].getPosition(); if(LLAvatarListEntry* entry = getAvatarEntry(mTrackedAvatar))
if (pos != LLTracker::getTrackedPositionGlobal())
{ {
std::string name = mAvatars[mTrackedAvatar].getName(); if (entry->getPosition() != LLTracker::getTrackedPositionGlobal())
if (!mUpdate)
{ {
name += "\n(last known position)"; trackAvatar(entry);
} }
LLTracker::trackLocation(pos, name, name);
} }
} }
else else
@@ -1050,6 +1055,17 @@ void LLFloaterAvatarList::refreshTracker()
} }
} }
void LLFloaterAvatarList::trackAvatar(const LLAvatarListEntry* entry)
{
if(!entry) return;
std::string name = entry->getName();
if (!mUpdate)
{
name += "\n(last known position)";
}
LLTracker::trackLocation(entry->getPosition(), name, name);
}
LLAvatarListEntry * LLFloaterAvatarList::getAvatarEntry(LLUUID avatar) LLAvatarListEntry * LLFloaterAvatarList::getAvatarEntry(LLUUID avatar)
{ {
if (avatar.isNull()) if (avatar.isNull())
@@ -1057,32 +1073,11 @@ LLAvatarListEntry * LLFloaterAvatarList::getAvatarEntry(LLUUID avatar)
return NULL; return NULL;
} }
std::map<LLUUID, LLAvatarListEntry>::iterator iter; av_list_t::iterator iter = std::find_if(mAvatars.begin(),mAvatars.end(),LLAvatarListEntry::uuidMatch(avatar));
if(iter != mAvatars.end())
iter = mAvatars.find(avatar); return &(*iter);
if (iter == mAvatars.end()) else
{
return NULL; return NULL;
}
return &iter->second;
}
//static
void LLFloaterAvatarList::onClickMark(void* userdata)
{
LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata;
LLDynamicArray<LLUUID> ids = self->mAvatarList->getSelectedIDs();
for (LLDynamicArray<LLUUID>::iterator itr = ids.begin(); itr != ids.end(); ++itr)
{
LLUUID avid = *itr;
LLAvatarListEntry* entry = self->getAvatarEntry(avid);
if (entry != NULL)
{
entry->toggleMark();
}
}
} }
BOOL LLFloaterAvatarList::handleKeyHere(KEY key, MASK mask) BOOL LLFloaterAvatarList::handleKeyHere(KEY key, MASK mask)
@@ -1094,8 +1089,7 @@ BOOL LLFloaterAvatarList::handleKeyHere(KEY key, MASK mask)
LLUUID agent_id = item->getUUID(); LLUUID agent_id = item->getUUID();
if (( KEY_RETURN == key ) && (MASK_NONE == mask)) if (( KEY_RETURN == key ) && (MASK_NONE == mask))
{ {
self->mFocusedAvatar = agent_id; self->setFocusAvatar(agent_id);
self->focusOnCurrent();
return TRUE; return TRUE;
} }
else if (( KEY_RETURN == key ) && (MASK_CONTROL == mask)) else if (( KEY_RETURN == key ) && (MASK_CONTROL == mask))
@@ -1142,143 +1136,73 @@ BOOL LLFloaterAvatarList::handleKeyHere(KEY key, MASK mask)
return LLPanel::handleKeyHere(key, mask); return LLPanel::handleKeyHere(key, mask);
} }
void LLFloaterAvatarList::onClickFocus(void* userdata) void LLFloaterAvatarList::onClickFocus()
{ {
LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; LLScrollListItem* item = mAvatarList->getFirstSelected();
LLScrollListItem* item = self->mAvatarList->getFirstSelected();
if (item) if (item)
{ {
self->mFocusedAvatar = item->getUUID(); setFocusAvatar(item->getUUID());
self->focusOnCurrent();
} }
} }
void LLFloaterAvatarList::removeFocusFromAll() void LLFloaterAvatarList::removeFocusFromAll()
{ {
std::map<LLUUID, LLAvatarListEntry>::iterator iter; BOOST_FOREACH(av_list_t::value_type& entry, mAvatars)
for (iter = mAvatars.begin(); iter != mAvatars.end(); iter++)
{ {
LLAvatarListEntry* entry = &iter->second; entry.setFocus(FALSE);
entry->setFocus(FALSE);
} }
} }
void LLFloaterAvatarList::focusOnCurrent() void LLFloaterAvatarList::setFocusAvatar(const LLUUID& id)
{ {
std::map<LLUUID, LLAvatarListEntry>::iterator iter; av_list_t::iterator iter = std::find_if(mAvatars.begin(),mAvatars.end(),LLAvatarListEntry::uuidMatch(id));
LLAvatarListEntry* entry; if(iter != mAvatars.end())
if (mAvatars.size() == 0)
{ {
return; if(!gAgentCamera.lookAtObject(id, false))
return;
removeFocusFromAll();
iter->setFocus(TRUE);
} }
}
for (iter = mAvatars.begin(); iter != mAvatars.end(); iter++) template<typename T>
void decrement_focus_target(T begin, T end, BOOL marked_only)
{
T iter = begin;
while(iter != end && !iter->isFocused()) ++iter;
if(iter == end)
return;
T prev_iter = iter;
while(prev_iter != begin)
{ {
entry = &iter->second; LLAvatarListEntry& entry = *(--prev_iter);
if(entry.isInList() && (entry.isMarked() || !marked_only) && gAgentCamera.lookAtObject(entry.getID(), false))
if (entry->isDead())
continue;
if (entry->getID() == mFocusedAvatar)
{ {
removeFocusFromAll(); iter->setFocus(FALSE);
entry->setFocus(TRUE); prev_iter->setFocus(TRUE);
gAgentCamera.lookAtObject(mFocusedAvatar, false); gAgentCamera.lookAtObject(prev_iter->getID(), false);
return; return;
} }
} }
gAgentCamera.lookAtObject(iter->getID(), false);
} }
void LLFloaterAvatarList::focusOnPrev(BOOL marked_only) void LLFloaterAvatarList::focusOnPrev(BOOL marked_only)
{ {
std::map<LLUUID, LLAvatarListEntry>::iterator iter; updateAvatarSorting();
LLAvatarListEntry* prev = NULL; decrement_focus_target(mAvatars.begin(), mAvatars.end(), marked_only);
LLAvatarListEntry* entry;
if (mAvatars.size() == 0)
{
return;
}
for (iter = mAvatars.begin(); iter != mAvatars.end(); iter++)
{
entry = &iter->second;
if (entry->isDead())
continue;
if (prev != NULL && entry->getID() == mFocusedAvatar)
{
break;
}
if ((!marked_only && entry->isDrawn()) || entry->isMarked())
{
prev = entry;
}
}
if (prev != NULL)
{
removeFocusFromAll();
prev->setFocus(TRUE);
mFocusedAvatar = prev->getID();
gAgentCamera.lookAtObject(mFocusedAvatar, false);
}
} }
void LLFloaterAvatarList::focusOnNext(BOOL marked_only) void LLFloaterAvatarList::focusOnNext(BOOL marked_only)
{ {
std::map<LLUUID, LLAvatarListEntry>::iterator iter; updateAvatarSorting();
BOOL found = FALSE; decrement_focus_target(mAvatars.rbegin(), mAvatars.rend(), marked_only);
LLAvatarListEntry* next = NULL;
LLAvatarListEntry* entry;
if (mAvatars.size() == 0)
{
return;
}
for (iter = mAvatars.begin(); iter != mAvatars.end(); iter++)
{
entry = &iter->second;
if (entry->isDead())
continue;
if (next == NULL && ((!marked_only && entry->isDrawn()) || entry->isMarked()))
{
next = entry;
}
if (found && ((!marked_only && entry->isDrawn()) || entry->isMarked()))
{
next = entry;
break;
}
if (entry->getID() == mFocusedAvatar)
{
found = TRUE;
}
}
if (next != NULL)
{
removeFocusFromAll();
next->setFocus(TRUE);
mFocusedAvatar = next->getID();
gAgentCamera.lookAtObject(mFocusedAvatar, false);
}
} }
/*static*/ /*static*/
void LLFloaterAvatarList::lookAtAvatar(LLUUID &uuid) void LLFloaterAvatarList::lookAtAvatar(LLUUID &uuid)
{ // twisted laws { // twisted laws
LLViewerObject* voavatar = gObjectList.findObject(uuid); LLVOAvatar* voavatar = gObjectList.findAvatar(uuid);
if(voavatar && voavatar->isAvatar()) if(voavatar && voavatar->isAvatar())
{ {
gAgentCamera.setFocusOnAvatar(FALSE, FALSE); gAgentCamera.setFocusOnAvatar(FALSE, FALSE);
@@ -1291,39 +1215,9 @@ void LLFloaterAvatarList::lookAtAvatar(LLUUID &uuid)
} }
} }
//static void LLFloaterAvatarList::onClickGetKey()
void LLFloaterAvatarList::onClickPrevInList(void* userdata)
{ {
LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; LLScrollListItem* item = mAvatarList->getFirstSelected();
self->focusOnPrev(FALSE);
}
//static
void LLFloaterAvatarList::onClickNextInList(void* userdata)
{
LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata;
self->focusOnNext(FALSE);
}
//static
void LLFloaterAvatarList::onClickPrevMarked(void* userdata)
{
LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata;
self->focusOnPrev(TRUE);
}
//static
void LLFloaterAvatarList::onClickNextMarked(void* userdata)
{
LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata;
self->focusOnNext(TRUE);
}
//static
void LLFloaterAvatarList::onClickGetKey(void *userdata)
{
LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata;
LLScrollListItem* item = self->mAvatarList->getFirstSelected();
if (NULL == item) return; if (NULL == item) return;
@@ -1334,7 +1228,7 @@ void LLFloaterAvatarList::onClickGetKey(void *userdata)
gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(buffer)); gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(buffer));
} }
//static
void LLFloaterAvatarList::sendKeys() void LLFloaterAvatarList::sendKeys()
{ {
LLViewerRegion* regionp = gAgent.getRegion(); LLViewerRegion* regionp = gAgent.getRegion();
@@ -1432,11 +1326,6 @@ bool LLFloaterAvatarList::onConfirmRadarChatKeys(const LLSD& notification, const
} }
return false; return false;
} }
//static
void LLFloaterAvatarList::onClickSendKeys(void *userdata)
{
LLFloaterAvatarList::getInstance()->sendKeys();
}
static void send_freeze(const LLUUID& avatar_id, bool freeze) static void send_freeze(const LLUUID& avatar_id, bool freeze)
{ {
@@ -1521,46 +1410,44 @@ static void send_estate_message(
msg->sendReliable(gAgent.getRegion()->getHost()); msg->sendReliable(gAgent.getRegion()->getHost());
} }
static void cmd_freeze(const LLUUID& avatar, const std::string& name) { send_freeze(avatar, true); } static void cmd_append_names(const LLAvatarListEntry* entry, std::string &str, std::string &sep)
static void cmd_unfreeze(const LLUUID& avatar, const std::string& name) { send_freeze(avatar, false); } { if(!str.empty())str.append(sep);str.append(entry->getName()); }
static void cmd_eject(const LLUUID& avatar, const std::string& name) { send_eject(avatar, false); } static void cmd_toggle_mark(LLAvatarListEntry* entry) { entry->toggleMark(); }
static void cmd_ban(const LLUUID& avatar, const std::string& name) { send_eject(avatar, true); } static void cmd_ar(const LLAvatarListEntry* entry) { LLFloaterReporter::showFromObject(entry->getID()); }
static void cmd_profile(const LLUUID& avatar, const std::string& name) { LLFloaterAvatarInfo::showFromDirectory(avatar); } static void cmd_profile(const LLAvatarListEntry* entry) { LLFloaterAvatarInfo::showFromDirectory(entry->getID()); }
static void cmd_estate_eject(const LLUUID& avatar, const std::string& name){ send_estate_message("teleporthomeuser", avatar); } static void cmd_teleport(const LLAvatarListEntry* entry) { gAgent.teleportViaLocation(entry->getPosition()); }
static void cmd_estate_ban(const LLUUID &avatar, const std::string &name) { LLPanelEstateInfo::sendEstateAccessDelta(ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | ESTATE_ACCESS_NO_REPLY, avatar); } static void cmd_freeze(const LLAvatarListEntry* entry) { send_freeze(entry->getID(), true); }
static void cmd_unfreeze(const LLAvatarListEntry* entry) { send_freeze(entry->getID(), false); }
static void cmd_eject(const LLAvatarListEntry* entry) { send_eject(entry->getID(), false); }
static void cmd_ban(const LLAvatarListEntry* entry) { send_eject(entry->getID(), true); }
static void cmd_estate_eject(const LLAvatarListEntry* entry){ send_estate_message("teleporthomeuser", entry->getID()); }
static void cmd_estate_ban(const LLAvatarListEntry* entry) { LLPanelEstateInfo::sendEstateAccessDelta(ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | ESTATE_ACCESS_NO_REPLY, entry->getID()); }
void LLFloaterAvatarList::doCommand(void (*func)(const LLUUID& avatar, const std::string& name)) void LLFloaterAvatarList::doCommand(avlist_command_t func, bool single/*=false*/)
{ {
LLDynamicArray<LLUUID> ids = mAvatarList->getSelectedIDs(); LLDynamicArray<LLUUID> ids;
if(!single)
ids = mAvatarList->getSelectedIDs();
else
ids.put(getSelectedID());
for (LLDynamicArray<LLUUID>::iterator itr = ids.begin(); itr != ids.end(); ++itr) for (LLDynamicArray<LLUUID>::iterator itr = ids.begin(); itr != ids.end(); ++itr)
{ {
LLUUID avid = *itr; LLUUID& avid = *itr;
if(avid.isNull())
continue;
LLAvatarListEntry* entry = getAvatarEntry(avid); LLAvatarListEntry* entry = getAvatarEntry(avid);
if (entry != NULL) if (entry != NULL)
{ {
llinfos << "Executing command on " << entry->getName() << llendl; llinfos << "Executing command on " << entry->getName() << llendl;
func(avid, entry->getName()); func(entry);
} }
} }
} }
std::string LLFloaterAvatarList::getSelectedNames(const std::string& separator) std::string LLFloaterAvatarList::getSelectedNames(const std::string& separator)
{ {
std::string ret = ""; std::string ret;
doCommand(boost::bind(&cmd_append_names,_1,ref(ret),separator));
LLDynamicArray<LLUUID> ids = mAvatarList->getSelectedIDs();
for (LLDynamicArray<LLUUID>::iterator itr = ids.begin(); itr != ids.end(); ++itr)
{
LLUUID avid = *itr;
LLAvatarListEntry* entry = getAvatarEntry(avid);
if (entry != NULL)
{
if (!ret.empty()) ret += separator;
ret += entry->getName();
}
}
return ret; return ret;
} }
@@ -1585,6 +1472,9 @@ LLUUID LLFloaterAvatarList::getSelectedID()
//static //static
void LLFloaterAvatarList::callbackFreeze(const LLSD& notification, const LLSD& response) void LLFloaterAvatarList::callbackFreeze(const LLSD& notification, const LLSD& response)
{ {
if(!instanceExists())
return;
S32 option = LLNotification::getSelectedOption(notification, response); S32 option = LLNotification::getSelectedOption(notification, response);
if (option == 0) if (option == 0)
@@ -1600,6 +1490,9 @@ void LLFloaterAvatarList::callbackFreeze(const LLSD& notification, const LLSD& r
//static //static
void LLFloaterAvatarList::callbackEject(const LLSD& notification, const LLSD& response) void LLFloaterAvatarList::callbackEject(const LLSD& notification, const LLSD& response)
{ {
if(!instanceExists())
return;
S32 option = LLNotification::getSelectedOption(notification, response); S32 option = LLNotification::getSelectedOption(notification, response);
if (option == 0) if (option == 0)
@@ -1615,6 +1508,9 @@ void LLFloaterAvatarList::callbackEject(const LLSD& notification, const LLSD& re
//static //static
void LLFloaterAvatarList::callbackEjectFromEstate(const LLSD& notification, const LLSD& response) void LLFloaterAvatarList::callbackEjectFromEstate(const LLSD& notification, const LLSD& response)
{ {
if(!instanceExists())
return;
S32 option = LLNotification::getSelectedOption(notification, response); S32 option = LLNotification::getSelectedOption(notification, response);
if (option == 0) if (option == 0)
@@ -1626,6 +1522,9 @@ void LLFloaterAvatarList::callbackEjectFromEstate(const LLSD& notification, cons
//static //static
void LLFloaterAvatarList::callbackBanFromEstate(const LLSD& notification, const LLSD& response) void LLFloaterAvatarList::callbackBanFromEstate(const LLSD& notification, const LLSD& response)
{ {
if(!instanceExists())
return;
S32 option = LLNotification::getSelectedOption(notification, response); S32 option = LLNotification::getSelectedOption(notification, response);
if (option == 0) if (option == 0)
@@ -1648,29 +1547,25 @@ void LLFloaterAvatarList::callbackIdle(void* userdata)
} }
} }
void LLFloaterAvatarList::onClickFreeze(void* userdata) void LLFloaterAvatarList::onClickFreeze()
{ {
LLSD args; LLSD args;
LLSD payload; LLSD payload;
args["AVATAR_NAME"] = ((LLFloaterAvatarList*)userdata)->getSelectedNames(); args["AVATAR_NAME"] = getSelectedNames();
LLNotificationsUtil::add("FreezeAvatarFullname", args, payload, callbackFreeze); LLNotificationsUtil::add("FreezeAvatarFullname", args, payload, callbackFreeze);
} }
//static void LLFloaterAvatarList::onClickEject()
void LLFloaterAvatarList::onClickEject(void* userdata)
{ {
LLSD args; LLSD args;
LLSD payload; LLSD payload;
args["AVATAR_NAME"] = ((LLFloaterAvatarList*)userdata)->getSelectedNames(); args["AVATAR_NAME"] = getSelectedNames();
LLNotificationsUtil::add("EjectAvatarFullname", args, payload, callbackEject); LLNotificationsUtil::add("EjectAvatarFullname", args, payload, callbackEject);
} }
//static void LLFloaterAvatarList::onClickMute()
void LLFloaterAvatarList::onClickMute(void* userdata)
{ {
LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; LLDynamicArray<LLUUID> ids = mAvatarList->getSelectedIDs();
LLDynamicArray<LLUUID> ids = self->mAvatarList->getSelectedIDs();
if (ids.size() > 0) if (ids.size() > 0)
{ {
for (LLDynamicArray<LLUUID>::iterator itr = ids.begin(); itr != ids.end(); ++itr) for (LLDynamicArray<LLUUID>::iterator itr = ids.begin(); itr != ids.end(); ++itr)
@@ -1695,62 +1590,25 @@ void LLFloaterAvatarList::onClickMute(void* userdata)
} }
} }
//static void LLFloaterAvatarList::onClickEjectFromEstate()
void LLFloaterAvatarList::onClickEjectFromEstate(void* userdata)
{ {
LLSD args; LLSD args;
LLSD payload; LLSD payload;
args["EVIL_USER"] = ((LLFloaterAvatarList*)userdata)->getSelectedNames(); args["EVIL_USER"] = getSelectedNames();
LLNotificationsUtil::add("EstateKickUser", args, payload, callbackEjectFromEstate); LLNotificationsUtil::add("EstateKickUser", args, payload, callbackEjectFromEstate);
} }
//static void LLFloaterAvatarList::onClickBanFromEstate()
void LLFloaterAvatarList::onClickBanFromEstate(void* userdata)
{ {
LLSD args; LLSD args;
LLSD payload; LLSD payload;
args["EVIL_USER"] = ((LLFloaterAvatarList*)userdata)->getSelectedNames(); args["EVIL_USER"] = getSelectedNames();
LLNotificationsUtil::add("EstateBanUser", args, payload, callbackBanFromEstate); LLNotificationsUtil::add("EstateBanUser", args, payload, callbackBanFromEstate);
} }
//static void LLFloaterAvatarList::onAvatarSortingChanged()
void LLFloaterAvatarList::onClickAR(void* userdata)
{ {
LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; mDirtyAvatarSorting = true;
LLScrollListItem* item = self->mAvatarList->getFirstSelected();
if (item)
{
LLUUID agent_id = item->getUUID();
LLAvatarListEntry* entry = self->getAvatarEntry(agent_id);
if (entry)
{
LLFloaterReporter::showFromObject(entry->getID());
}
}
}
// static
void LLFloaterAvatarList::onClickProfile(void* userdata)
{
LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata;
self->doCommand(cmd_profile);
}
//static
void LLFloaterAvatarList::onClickTeleport(void* userdata)
{
LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata;
LLScrollListItem* item = self->mAvatarList->getFirstSelected();
if (item)
{
LLUUID agent_id = item->getUUID();
LLAvatarListEntry* entry = self->getAvatarEntry(agent_id);
if (entry)
{
// llinfos << "Trying to teleport to " << entry->getName() << " at " << entry->getPosition() << llendl;
gAgent.teleportViaLocation(entry->getPosition());
}
}
} }
void LLFloaterAvatarList::onSelectName() void LLFloaterAvatarList::onSelectName()
@@ -1770,9 +1628,7 @@ void LLFloaterAvatarList::onSelectName()
} }
} }
void LLFloaterAvatarList::onCommitUpdateRate(LLUICtrl*, void* userdata) void LLFloaterAvatarList::onCommitUpdateRate()
{ {
LLFloaterAvatarList* self = (LLFloaterAvatarList*)userdata; mUpdateRate = gSavedSettings.getU32("RadarUpdateRate") * 3 + 3;
self->mUpdateRate = gSavedSettings.getU32("RadarUpdateRate") * 3 + 3;
} }

View File

@@ -59,7 +59,7 @@ enum ACTIVITY_TYPE
*/ */
void setPosition(LLVector3d position, bool this_sim, bool drawn, bool chatrange, bool shoutrange); void setPosition(LLVector3d position, bool this_sim, bool drawn, bool chatrange, bool shoutrange);
LLVector3d getPosition() { return mPosition; } const LLVector3d& getPosition() const { return mPosition; }
/** /**
* @brief Returns the age of this entry in frames * @brief Returns the age of this entry in frames
@@ -72,46 +72,61 @@ enum ACTIVITY_TYPE
/** /**
* @brief Returns the age of this entry in seconds * @brief Returns the age of this entry in seconds
*/ */
F32 getEntryAgeSeconds(); F32 getEntryAgeSeconds() const;
/** /**
* @brief Returns the name of the avatar * @brief Returns the name of the avatar
*/ */
std::string getName() { return mName; } const std::string& getName() const { return mName; }
/** /**
* @brief Returns the ID of the avatar * @brief Returns the ID of the avatar
*/ */
LLUUID getID() { return mID; } const LLUUID& getID() const { return mID; }
void setActivity(ACTIVITY_TYPE activity); void setActivity(ACTIVITY_TYPE activity);
/** /**
* @brief Returns the activity type * @brief Returns the activity type
*/ */
ACTIVITY_TYPE getActivity(); const ACTIVITY_TYPE getActivity();
/** /**
* @brief Sets the 'focus' status on this entry (camera focused on this avatar) * @brief Sets the 'focus' status on this entry (camera focused on this avatar)
*/ */
void setFocus(BOOL value) { mFocused = value; } void setFocus(BOOL value) { mFocused = value; }
BOOL isFocused() { return mFocused; } bool isFocused() const { return mFocused; }
BOOL isMarked() { return mMarked; } bool isMarked() const { return mMarked; }
BOOL isDrawn() { return (mInDrawFrame != U32_MAX); } bool isDrawn() const { return (mInDrawFrame != U32_MAX); }
BOOL isInSim() { return (mInSimFrame != U32_MAX); } bool isInSim() const { return (mInSimFrame != U32_MAX); }
/**
* @brief 'InList' signifies that the entry has been displayed in the floaters avatar list
* Until this happens our focusprev/focusnext logic should ignore this entry.
*/
void setInList() { mIsInList = true; }
bool isInList() const { return mIsInList; }
/** /**
* @brief Returns whether the item is dead and shouldn't appear in the list * @brief Returns whether the item is dead and shouldn't appear in the list
* @returns TRUE if dead * @returns TRUE if dead
*/ */
BOOL isDead(); bool isDead() const;
void toggleMark() { mMarked = !mMarked; } void toggleMark() { mMarked = !mMarked; }
struct uuidMatch
{
uuidMatch(const LLUUID& id) : mID(id) {}
bool operator()(const LLAvatarListEntry& l) { return l.getID() == mID; }
LLUUID mID;
};
private: private:
friend class LLFloaterAvatarList; friend class LLFloaterAvatarList;
@@ -119,8 +134,9 @@ private:
std::string mName; std::string mName;
LLVector3d mPosition; LLVector3d mPosition;
LLVector3d mDrawPosition; LLVector3d mDrawPosition;
BOOL mMarked; bool mMarked;
BOOL mFocused; bool mFocused;
bool mIsInList;
/** /**
* @brief Timer to keep track of whether avatars are still there * @brief Timer to keep track of whether avatars are still there
@@ -212,7 +228,9 @@ public:
static void lookAtAvatar(LLUUID &uuid); static void lookAtAvatar(LLUUID &uuid);
static void sound_trigger_hook(LLMessageSystem* msg,void **); static void sound_trigger_hook(LLMessageSystem* msg,void **);
static void sendKeys(); void sendKeys();
typedef std::vector<LLAvatarListEntry> av_list_t;
private: private:
// when a line editor loses keyboard focus, it is committed. // when a line editor loses keyboard focus, it is committed.
@@ -230,8 +248,7 @@ private:
LIST_CLIENT, LIST_CLIENT,
}; };
typedef boost::function<void (LLAvatarListEntry*)> avlist_command_t;
typedef void (*avlist_command_t)(const LLUUID &avatar, const std::string &name);
/** /**
* @brief Removes focus status from all avatars in list * @brief Removes focus status from all avatars in list
@@ -239,9 +256,9 @@ private:
void removeFocusFromAll(); void removeFocusFromAll();
/** /**
* @brief Focus camera on current avatar * @brief Focus camera on specified avatar
*/ */
void focusOnCurrent(); void setFocusAvatar(const LLUUID& id);
/** /**
* @brief Focus camera on previous avatar * @brief Focus camera on previous avatar
@@ -255,6 +272,9 @@ private:
*/ */
void focusOnNext(BOOL marked_only); void focusOnNext(BOOL marked_only);
void refreshTracker();
void trackAvatar(const LLAvatarListEntry* entry);
/** /**
* @brief Handler for the "refresh" button click. * @brief Handler for the "refresh" button click.
* I am unsure whether this is actually necessary at the time. * I am unsure whether this is actually necessary at the time.
@@ -263,42 +283,38 @@ private:
* @param userdata Pointer to user data (LLFloaterAvatarList instance) * @param userdata Pointer to user data (LLFloaterAvatarList instance)
*/ */
static void onClickProfile(void *userdata); void onClickIM();
static void onClickIM(void *userdata); void onClickTeleportOffer();
static void onClickTeleportOffer(void *userdata); void onClickTrack();
static void onClickTrack(void *userdata); void onClickMute();
static void onClickMark(void *userdata); void onClickFocus();
static void onClickFocus(void *userdata); void onClickGetKey();
static void onClickPrevInList(void *userdata); void onSelectName();
static void onClickNextInList(void *userdata); void onCommitUpdateRate();
static void onClickPrevMarked(void *userdata);
static void onClickNextMarked(void *userdata);
static void onClickGetKey(void *userdata);
static void onClickFreeze(void *userdata); /**
static void onClickEject(void *userdata); * @brief These callbacks fire off notifications, which THEN fire the related callback* functions.
static void onClickMute(void *userdata); */
static void onClickAR(void *userdata); void onClickFreeze();
static void onClickTeleport(void *userdata); void onClickEject();
static void onClickEjectFromEstate(void *userdata); void onClickEjectFromEstate();
static void onClickBanFromEstate(void *userdata); void onClickBanFromEstate();
void onAvatarSortingChanged();
/**
* @brief Called via notification feedback.
*/
static void callbackFreeze(const LLSD& notification, const LLSD& response); static void callbackFreeze(const LLSD& notification, const LLSD& response);
static void callbackEject(const LLSD& notification, const LLSD& response); static void callbackEject(const LLSD& notification, const LLSD& response);
static void callbackAR(void *userdata);
static void callbackEjectFromEstate(const LLSD& notification, const LLSD& response); static void callbackEjectFromEstate(const LLSD& notification, const LLSD& response);
static void callbackBanFromEstate(const LLSD& notification, const LLSD& response); static void callbackBanFromEstate(const LLSD& notification, const LLSD& response);
static void onSelectName();
static void onCommitUpdateRate(LLUICtrl*, void *userdata);
static void onClickSendKeys(void *userdata);
static bool onConfirmRadarChatKeys(const LLSD& notification, const LLSD& response ); static bool onConfirmRadarChatKeys(const LLSD& notification, const LLSD& response );
static void callbackIdle(void *userdata); static void callbackIdle(void *userdata);
void doCommand(avlist_command_t cmd); void doCommand(avlist_command_t cmd, bool single = false);
/** /**
* @brief Cleanup avatar list, removing dead entries from it. * @brief Cleanup avatar list, removing dead entries from it.
@@ -307,28 +323,28 @@ private:
* to do something to them. * to do something to them.
*/ */
void expireAvatarList(); void expireAvatarList();
void updateAvatarSorting();
private: private:
/** /**
* @brief Pointer to the avatar scroll list * @brief Pointer to the avatar scroll list
*/ */
LLScrollListCtrl* mAvatarList; LLScrollListCtrl* mAvatarList;
std::map<LLUUID, LLAvatarListEntry> mAvatars; av_list_t mAvatars;
bool mDirtyAvatarSorting;
/** /**
* @brief TRUE when Updating * @brief TRUE when Updating
*/ */
BOOL mUpdate; bool mUpdate;
/** /**
* @brief Update rate (if min frames per update) * @brief Update rate (if min frames per update)
*/ */
U32 mUpdateRate; U32 mUpdateRate;
void refreshTracker();
// tracking data // tracking data
BOOL mTracking; // Tracking ? bool mTracking; // Tracking ?
LLUUID mTrackedAvatar; // Who we are tracking LLUUID mTrackedAvatar; // Who we are tracking
/** /**