373 lines
9.3 KiB
C++
373 lines
9.3 KiB
C++
//
|
|
// C++ Interface: llfloateravatarlist
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Original author: Dale Glass <dale@daleglass.net>, (C) 2007
|
|
// Heavily modified by Henri Beauchamp 10/2009.
|
|
//
|
|
// Copyright: See COPYING file that comes with this distribution
|
|
//
|
|
//
|
|
#include "llavatarname.h"
|
|
#include "llavatarpropertiesprocessor.h"
|
|
#include "llfloater.h"
|
|
#include "llfloaterreporter.h"
|
|
#include "lluuid.h"
|
|
#include "lltimer.h"
|
|
#include "llscrolllistctrl.h"
|
|
|
|
#include <time.h>
|
|
#include <map>
|
|
#include <set>
|
|
|
|
#include <boost/shared_ptr.hpp>
|
|
|
|
class LLFloaterAvatarList;
|
|
|
|
/**
|
|
* @brief This class is used to hold data about avatars.
|
|
* We cache data about avatars to avoid repeating requests in this class.
|
|
* Instances are kept in a map<LLAvatarListEntry>. We keep track of the
|
|
* frame where the avatar was last seen.
|
|
*/
|
|
class LLAvatarListEntry : public LLAvatarPropertiesObserver
|
|
{
|
|
|
|
public:
|
|
|
|
enum ACTIVITY_TYPE
|
|
{
|
|
ACTIVITY_NONE, /** Avatar not doing anything */
|
|
ACTIVITY_MOVING, /** Changing position */
|
|
ACTIVITY_GESTURING, /** Playing a gesture */
|
|
ACTIVITY_REZZING, /** Rezzing objects */
|
|
ACTIVITY_PARTICLES, /** Creating particles */
|
|
ACTIVITY_TYPING, /** Typing */
|
|
ACTIVITY_NEW, /** Avatar just appeared */
|
|
ACTIVITY_SOUND, /** Playing a sound */
|
|
ACTIVITY_DEAD /** Avatar isn't around anymore, and will be removed soon from the list */
|
|
};
|
|
/**
|
|
* @brief Initializes a list entry
|
|
* @param id Avatar's key
|
|
* @param name Avatar's name
|
|
* @param position Avatar's current position
|
|
*/
|
|
LLAvatarListEntry(const LLUUID& id = LLUUID::null, const std::string &name = "", const LLVector3d &position = LLVector3d::zero);
|
|
~LLAvatarListEntry();
|
|
|
|
// Get properties, such as age and other niceties displayed on profiles.
|
|
/*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
|
|
|
|
/**
|
|
* Update world position.
|
|
* Affects age.
|
|
*/
|
|
void setPosition(LLVector3d position, bool this_sim, bool drawn, bool chatrange, bool shoutrange);
|
|
|
|
const LLVector3d& getPosition() const { return mPosition; }
|
|
|
|
/**
|
|
* @brief Returns the age of this entry in frames
|
|
*
|
|
* This is only used for determining whether the avatar is still around.
|
|
* @see getEntryAgeSeconds
|
|
*/
|
|
bool getAlive();
|
|
|
|
/**
|
|
* @brief Returns the age of this entry in seconds
|
|
*/
|
|
F32 getEntryAgeSeconds() const;
|
|
|
|
/**
|
|
* @brief Returns the name of the avatar
|
|
*/
|
|
const std::string& getName() const { return mName; }
|
|
const time_t& getTime() const { return mTime; }
|
|
|
|
/**
|
|
* @brief Returns the ID of the avatar
|
|
*/
|
|
const LLUUID& getID() const { return mID; }
|
|
|
|
void setActivity(ACTIVITY_TYPE activity);
|
|
|
|
/**
|
|
* @brief Returns the activity type
|
|
*/
|
|
const ACTIVITY_TYPE getActivity();
|
|
|
|
/**
|
|
* @brief Sets the 'focus' status on this entry (camera focused on this avatar)
|
|
*/
|
|
void setFocus(BOOL value) { mFocused = value; }
|
|
|
|
bool isFocused() const { return mFocused; }
|
|
|
|
bool isMarked() const { return mMarked; }
|
|
|
|
bool isDrawn() const { return (mInDrawFrame != 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
|
|
* @returns TRUE if dead
|
|
*/
|
|
bool isDead() const;
|
|
|
|
void toggleMark() { mMarked = !mMarked; }
|
|
|
|
struct uuidMatch
|
|
{
|
|
uuidMatch(const LLUUID& id) : mID(id) {}
|
|
bool operator()(const boost::shared_ptr<LLAvatarListEntry>& l) { return l->getID() == mID; }
|
|
LLUUID mID;
|
|
};
|
|
|
|
private:
|
|
friend class LLFloaterAvatarList;
|
|
|
|
LLUUID mID;
|
|
std::string mName;
|
|
time_t mTime;
|
|
LLVector3d mPosition;
|
|
LLVector3d mDrawPosition;
|
|
bool mMarked;
|
|
bool mFocused;
|
|
bool mIsInList;
|
|
bool mAgeAlert;
|
|
int mAge;
|
|
|
|
/**
|
|
* @brief Timer to keep track of whether avatars are still there
|
|
*/
|
|
|
|
LLTimer mUpdateTimer;
|
|
|
|
ACTIVITY_TYPE mActivityType;
|
|
|
|
LLTimer mActivityTimer;
|
|
|
|
/**
|
|
* @brief Last frame when this avatar was updated
|
|
*/
|
|
U32 mFrame;
|
|
//last frame when this avatar was in sim
|
|
U32 mInSimFrame;
|
|
//last frame when this avatar was in draw
|
|
U32 mInDrawFrame;
|
|
//last frame when this avatar was in shout range
|
|
U32 mInShoutFrame;
|
|
//last frame when this avatar was in chat range
|
|
U32 mInChatFrame;
|
|
};
|
|
|
|
|
|
/**
|
|
* @brief Avatar List
|
|
* Implements an avatar scanner in the client.
|
|
*
|
|
* This is my first attempt to modify the SL source. This code is intended
|
|
* to have a dual purpose: doing the task, and providing an example of how
|
|
* to do it. For that reason, it's going to be commented as exhaustively
|
|
* as possible.
|
|
*
|
|
* Since I'm very new to C++ any suggestions on coding, style, etc are very
|
|
* welcome.
|
|
*/
|
|
class LLFloaterAvatarList : public LLFloater, public LLSingleton<LLFloaterAvatarList>
|
|
{
|
|
/**
|
|
* @brief Creates and initializes the LLFloaterAvatarList
|
|
* Here the interface is created, and callbacks are initialized.
|
|
*/
|
|
friend class LLSingleton<LLFloaterAvatarList>;
|
|
private:
|
|
LLFloaterAvatarList();
|
|
public:
|
|
~LLFloaterAvatarList();
|
|
|
|
virtual BOOL handleKeyHere(KEY key, MASK mask);
|
|
|
|
/*virtual*/ void onClose(bool app_quitting);
|
|
/*virtual*/ void onOpen();
|
|
/*virtual*/ BOOL postBuild();
|
|
/*virtual*/ void draw();
|
|
static void createInstance(bool visible);
|
|
/**
|
|
* @brief Toggles interface visibility
|
|
* There is only one instance of the avatar scanner at any time.
|
|
*/
|
|
static void toggle(void*);
|
|
|
|
static void showInstance();
|
|
|
|
// Decides which user-chosen columns to show and hide.
|
|
void assessColumns();
|
|
|
|
/**
|
|
* @brief Updates the internal avatar list with the currently present avatars.
|
|
*/
|
|
void updateAvatarList();
|
|
|
|
/**
|
|
* @brief Refresh avatar list (display)
|
|
*/
|
|
void refreshAvatarList();
|
|
|
|
/**
|
|
* @brief Returns the entry for an avatar, if preset
|
|
* @returns Pointer to avatar entry, NULL if not found.
|
|
*/
|
|
LLAvatarListEntry* getAvatarEntry(LLUUID avatar);
|
|
|
|
/**
|
|
* @brief Returns a string with the selected names in the list
|
|
*/
|
|
std::string getSelectedNames(const std::string& separator = ", ");
|
|
std::string getSelectedName();
|
|
LLUUID getSelectedID();
|
|
|
|
static void lookAtAvatar(LLUUID &uuid);
|
|
|
|
static void sound_trigger_hook(LLMessageSystem* msg,void **);
|
|
void sendKeys();
|
|
|
|
typedef boost::shared_ptr<LLAvatarListEntry> LLAvatarListEntryPtr;
|
|
typedef std::vector< LLAvatarListEntryPtr > av_list_t;
|
|
|
|
private:
|
|
// when a line editor loses keyboard focus, it is committed.
|
|
// commit callbacks are named onCommitWidgetName by convention.
|
|
//void onCommitBaz(LLUICtrl* ctrl, void *userdata);
|
|
|
|
enum AVATARS_COLUMN_ORDER
|
|
{
|
|
LIST_MARK,
|
|
LIST_AVATAR_NAME,
|
|
LIST_DISTANCE,
|
|
LIST_POSITION,
|
|
LIST_ALTITUDE,
|
|
LIST_ACTIVITY,
|
|
LIST_AGE,
|
|
LIST_TIME,
|
|
LIST_CLIENT,
|
|
};
|
|
|
|
typedef boost::function<void (LLAvatarListEntry*)> avlist_command_t;
|
|
|
|
/**
|
|
* @brief Removes focus status from all avatars in list
|
|
*/
|
|
void removeFocusFromAll();
|
|
|
|
/**
|
|
* @brief Focus camera on specified avatar
|
|
*/
|
|
void setFocusAvatar(const LLUUID& id);
|
|
|
|
/**
|
|
* @brief Focus camera on previous avatar
|
|
* @param marked_only Whether to choose only marked avatars
|
|
*/
|
|
void focusOnPrev(BOOL marked_only);
|
|
|
|
/**
|
|
* @brief Focus camera on next avatar
|
|
* @param marked_only Whether to choose only marked avatars
|
|
*/
|
|
void focusOnNext(BOOL marked_only);
|
|
|
|
void refreshTracker();
|
|
void trackAvatar(const LLAvatarListEntry* entry);
|
|
|
|
/**
|
|
* @brief Handler for the "refresh" button click.
|
|
* I am unsure whether this is actually necessary at the time.
|
|
*
|
|
* LL: By convention, button callbacks are named onClickButtonLabel
|
|
* @param userdata Pointer to user data (LLFloaterAvatarList instance)
|
|
*/
|
|
|
|
void onClickIM();
|
|
void onClickTeleportOffer();
|
|
void onClickTrack();
|
|
void onClickMute();
|
|
void onClickFocus();
|
|
void onClickGetKey();
|
|
|
|
void onSelectName();
|
|
void onCommitUpdateRate();
|
|
|
|
/**
|
|
* @brief These callbacks fire off notifications, which THEN fire the related callback* functions.
|
|
*/
|
|
void onClickFreeze();
|
|
void onClickEject();
|
|
void onClickEjectFromEstate();
|
|
void onClickBanFromEstate();
|
|
void onAvatarSortingChanged();
|
|
|
|
/**
|
|
* @brief Called via notification feedback.
|
|
*/
|
|
static void callbackFreeze(const LLSD& notification, const LLSD& response);
|
|
static void callbackEject(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 bool onConfirmRadarChatKeys(const LLSD& notification, const LLSD& response );
|
|
|
|
static void callbackIdle(void *userdata);
|
|
|
|
void doCommand(avlist_command_t cmd, bool single = false);
|
|
|
|
/**
|
|
* @brief Cleanup avatar list, removing dead entries from it.
|
|
* This lets dead entries remain for some time. This makes it possible
|
|
* to keep people passing by in the list long enough that it's possible
|
|
* to do something to them.
|
|
*/
|
|
void expireAvatarList();
|
|
void updateAvatarSorting();
|
|
|
|
private:
|
|
/**
|
|
* @brief Pointer to the avatar scroll list
|
|
*/
|
|
LLScrollListCtrl* mAvatarList;
|
|
av_list_t mAvatars;
|
|
bool mDirtyAvatarSorting;
|
|
|
|
/**
|
|
* @brief TRUE when Updating
|
|
*/
|
|
bool mUpdate;
|
|
|
|
/**
|
|
* @brief Update rate (if min frames per update)
|
|
*/
|
|
U32 mUpdateRate;
|
|
|
|
// tracking data
|
|
bool mTracking; // Tracking ?
|
|
LLUUID mTrackedAvatar; // Who we are tracking
|
|
|
|
/**
|
|
* @brief Avatar the camera is focused on
|
|
*/
|
|
LLUUID mFocusedAvatar;
|
|
};
|