summaryrefslogtreecommitdiff
path: root/indra/newview/llavatarlist.cpp
diff options
context:
space:
mode:
authorSteven Bennetts <steve@lindenlab.com>2009-09-29 19:37:05 +0000
committerSteven Bennetts <steve@lindenlab.com>2009-09-29 19:37:05 +0000
commit606b381c9fbc43c214afd26fb2e2598eec656b66 (patch)
tree422a6d5d94d50bd97ac5bcbdb52f0f6de083c6e7 /indra/newview/llavatarlist.cpp
parent751cc7cf68bb4d766e8ecaaf76af054dcfbbe9dc (diff)
merge https://svn.aws.productengine.com/secondlife/export-from-ll/viewer-2-0@1830 https://svn.aws.productengine.com/secondlife/pe/stable-2@1839 -> viewer-2.0.0-3
JIRAS: EXT-96 EXT-204 EXT-312 EXT-334 EXT-479 EXT-498 EXT-514 EXT-637 EXT-647 EXT-746 EXT-748 EXT-749 EXT-757 EXT-789 EXT-794 EXT-808 EXT-817 EXT-823 EXT-831 EXT-834 EXT-837 EXT-844 EXT-848 EXT-862 EXT-876 EXT-896 EXT-897 EXT-898 EXT-899 EXT-910 EXT-912 EXT-918 EXT-921 EXT-925 EXT-926 EXT-928 EXT-930 EXT-931 EXT-935 EXT-938 EXT-939 EXT-952 EXT-985 EXT-986 EXT-992 EXT-994 EXT-995 EXT-996 EXT-997 EXT-998 EXT-1001 EXT-1004 EXT-1010 EXT-1012 EXT-1016 EXT-1018 EXT-1020 EXT-1028 EXT-1041 EXT-1044 EXT-1051 EXT-1052 EXT-1061 EXT-1069 EXT-1071 EXT-1074 EXT-1075 EXT-1076 EXT-1078 EXT-1080 EXT-1081 EXT-1082 EXT-1083 EXT-1085 EXT-1092 EXT-1093 EXT-1099 EXT-1100 EXT-1101 EXT-1104 EXT-1106 EXT-1111 EXT-1113 EXT-1114 EXT-1115 EXT-1116 EXT-1118 EXT-1119 EXT-1129 EXT-1132 EXT-1135 EXT-1138 EXT-1142 EXT-1161 EXT-1162 EXT-1178 EXT-1180 * NEW DEVELOPMENT: * EXT-898 - Add dock/undock support for camera and movement controls * Avatar list changes * Bottom bar changes: menu, docking, visibility * Camera changes * Camera & Movement Floaters * Dockable Floaters (LLDockableFloater) * Removed LLListCtrl * Toast / Notification changes: signal / destruction changes, ordering * Nearby chat input should display active voice indicator QA NOTES: * Message Well Window is ready to be tested for regression & matching the spec. * Verify Group List Item L&F * Verify All tabs in People Panel * Verify that Picks behavior is not changed
Diffstat (limited to 'indra/newview/llavatarlist.cpp')
-rw-r--r--indra/newview/llavatarlist.cpp506
1 files changed, 106 insertions, 400 deletions
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index 2e64c10bb2..ee14a2ff86 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -37,144 +37,9 @@
// newview
#include "llcallingcard.h" // for LLAvatarTracker
#include "llcachename.h"
-#include "lloutputmonitorctrl.h"
#include "llvoiceclient.h"
static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list");
-static LLDefaultChildRegistry::Register<LLAvatarListTmp> r_tmp("avatar_list_tmp");
-
-static const std::string COMMENT_TEXTBOX = "comment_text";
-
-LLAvatarList::Params::Params()
-:
- volume_column_width("volume_column_width", 0)
- , online_go_first("online_go_first", true)
-{
- draw_heading = true;
- draw_stripes = false;
- multi_select = false;
- column_padding = 0;
- search_column = COL_NAME;
- sort_column = COL_NAME;
-}
-
-LLAvatarList::LLAvatarList(const Params& p)
-: LLScrollListCtrl(p)
- , mHaveVolumeColumn(p.volume_column_width > 0)
- , mOnlineGoFirst(p.online_go_first)
-{
- setCommitOnSelectionChange(TRUE); // there's no such param in LLScrollListCtrl::Params
-
- // display a context menu appropriate for a list of avatar names
- setContextMenu(LLScrollListCtrl::MENU_AVATAR);
-
- // "volume" column
- {
- LLScrollListColumn::Params col_params;
- col_params.name = "volume";
- col_params.header.label = "Volume"; // *TODO: localize or remove the header
- col_params.width.pixel_width = p.volume_column_width;
- addColumn(col_params);
- }
-
- // "name" column
- {
- LLScrollListColumn::Params col_params;
- col_params.name = "name";
- col_params.header.label = "Name"; // *TODO: localize or remove the header
- col_params.width.dynamic_width = true;
- addColumn(col_params);
- }
-
- // "online status" column
- {
- LLScrollListColumn::Params col_params;
- col_params.name = "online";
- col_params.header.label = "Online"; // *TODO: localize or remove the header
- col_params.width.pixel_width = 0; // invisible column
- addColumn(col_params);
- }
-
-
- // invisible "id" column
- {
- LLScrollListColumn::Params col_params;
- col_params.name = "id";
- col_params.header.label = "ID"; // *TODO: localize or remove the header
- col_params.width.pixel_width = 0;
- addColumn(col_params);
- }
-
- // Primary sort = online status, secondary sort = name
- // The corresponding parameters don't work because we create columns dynamically.
- sortByColumnIndex(COL_NAME, TRUE);
- if (mOnlineGoFirst)
- sortByColumnIndex(COL_ONLINE, FALSE);
- setSearchColumn(COL_NAME);
-}
-
-// virtual
-void LLAvatarList::draw()
-{
- LLScrollListCtrl::draw();
- if (mHaveVolumeColumn)
- {
- updateVolume();
- }
-}
-
-std::vector<LLUUID> LLAvatarList::getSelectedIDs()
-{
- LLUUID selected_id;
- std::vector<LLUUID> avatar_ids;
- std::vector<LLScrollListItem*> selected = getAllSelected();
- for(std::vector<LLScrollListItem*>::iterator itr = selected.begin(); itr != selected.end(); ++itr)
- {
- avatar_ids.push_back((*itr)->getUUID());
- }
- return avatar_ids;
-}
-
-void LLAvatarList::addItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos)
-{
- std::string fullname;
-
- // Populate list item.
- LLSD element;
- element["id"] = id;
-
- // Update volume column (if we have one)
- {
- std::string icon = mHaveVolumeColumn ? getVolumeIcon(id) : "";
- LLSD& volume_column = element["columns"][COL_VOLUME];
- volume_column["column"] = "volume";
- volume_column["type"] = "icon";
- volume_column["value"] = icon;
- }
-
- LLSD& friend_column = element["columns"][COL_NAME];
- friend_column["column"] = "name";
- friend_column["value"] = name;
-
- LLSD& online_column = element["columns"][COL_ONLINE];
- online_column["column"] = "online";
- online_column["value"] = is_bold ? "1" : "0";
-
- LLScrollListItem* new_itemp = addElement(element, pos);
-
- // Indicate buddy online status.
- // (looks like parsing font parameters from LLSD is broken)
- if (is_bold)
- {
- LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(new_itemp->getColumn(COL_NAME));
- if (name_textp)
- name_textp->setFontStyle(LLFontGL::BOLD);
- else
- {
- llwarns << "Name column not found" << llendl;
- }
- }
-}
static bool findInsensitive(std::string haystack, const std::string& needle_upper)
{
@@ -182,136 +47,12 @@ static bool findInsensitive(std::string haystack, const std::string& needle_uppe
return haystack.find(needle_upper) != std::string::npos;
}
-BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::string& name_filter)
-{
- BOOL have_names = TRUE;
-
- // Save selection.
- std::vector<LLUUID> selected_ids = getSelectedIDs();
- LLUUID current_id = getCurrentID();
- S32 pos = getScrollPos();
-
- std::vector<LLUUID>::const_iterator buddy_it = all_buddies.begin();
- deleteAllItems();
- for(; buddy_it != all_buddies.end(); ++buddy_it)
- {
- std::string name;
- const LLUUID& buddy_id = *buddy_it;
- have_names &= gCacheName->getFullName(buddy_id, name);
- if (name_filter != LLStringUtil::null && !findInsensitive(name, name_filter))
- continue;
- addItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
- }
-
- // Changed item in place, need to request sort and update columns
- // because we might have changed data in a column on which the user
- // has already sorted. JC
- updateSort();
-
- // re-select items
- selectMultiple(selected_ids);
- setCurrentByID(current_id);
-#if 0
- // Restore selection.
- if(selected_ids.size() > 0)
- {
- // only non-null if friends was already found. This may fail,
- // but we don't really care here, because refreshUI() will
- // clean up the interface.
- for(std::vector<LLUUID>::iterator itr = selected_ids.begin(); itr != selected_ids.end(); ++itr)
- {
- setSelectedByValue(*itr, true);
- }
- }
-#endif
- setScrollPos(pos);
-
- updateLineHeight();
- LLRect rect = getRequiredRect();
-
- LLSD params;
- params["action"] = "size_changes";
- params["width"] = rect.getWidth();
- params["height"] = llmax(rect.getHeight(),20) + 5;
-
- getParent()->notifyParent(params);
-
- return have_names;
-}
-// static
-std::string LLAvatarList::getVolumeIcon(const LLUUID& id)
-{
- //
- // Determine icon appropriate for the current avatar volume.
- //
- // *TODO: remove this in favor of LLOutputMonitorCtrl
- // when ListView widget is implemented
- // which is capable of containing arbitrary widgets.
- //
- static LLOutputMonitorCtrl::Params default_monitor_params(LLUICtrlFactory::getDefaultParams<LLOutputMonitorCtrl>());
- bool muted = gVoiceClient->getIsModeratorMuted(id) || gVoiceClient->getOnMuteList(id);
- F32 power = gVoiceClient->getCurrentPower(id);
- std::string icon;
-
- if (muted)
- {
- icon = default_monitor_params.image_mute.name;
- }
- else if (power == 0.f)
- {
- icon = default_monitor_params.image_off.name;
- }
- else if (power < LLVoiceClient::OVERDRIVEN_POWER_LEVEL)
- {
- S32 icon_image_idx = llmin(2, llfloor((power / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 3.f));
- switch(icon_image_idx)
- {
- default:
- case 0:
- icon = default_monitor_params.image_on.name;
- break;
- case 1:
- icon = default_monitor_params.image_level_1.name;
- break;
- case 2:
- icon = default_monitor_params.image_level_2.name;
- break;
- }
- }
- else
- {
- // overdriven
- icon = default_monitor_params.image_level_3.name;
- }
-
- return icon;
-}
-
-// Update volume column for all list rows.
-void LLAvatarList::updateVolume()
-{
- item_list& items = getItemList();
+//comparators
+static const LLAvatarItemNameComparator NAME_COMPARATOR;
+static const LLFlatListView::ItemReverseComparator REVERSE_NAME_COMPARATOR(NAME_COMPARATOR);
- for (item_list::iterator item_it = items.begin();
- item_it != items.end();
- ++item_it)
- {
- LLScrollListItem* itemp = (*item_it);
- LLUUID speaker_id = itemp->getUUID();
-
- LLScrollListCell* icon_cell = itemp->getColumn(COL_VOLUME);
- if (icon_cell)
- icon_cell->setValue(getVolumeIcon(speaker_id));
- }
-}
-
-
-
-
-#include "llavatarlistitem.h"
-
-LLAvatarListTmp::Params::Params()
+LLAvatarList::Params::Params()
:
volume_column_width("volume_column_width", 0)
, online_go_first("online_go_first", true)
@@ -320,198 +61,163 @@ volume_column_width("volume_column_width", 0)
-LLAvatarListTmp::LLAvatarListTmp(const Params& p)
+LLAvatarList::LLAvatarList(const Params& p)
: LLFlatListView(p)
-, mHaveVolumeColumn(p.volume_column_width > 0)
, mOnlineGoFirst(p.online_go_first)
+, mContextMenu(NULL)
{
- LLRect item_list_rect = getLocalRect();
- item_list_rect.stretch( -getBorderWidth());
-
- LLTextBox::Params text_p;
- text_p.name(COMMENT_TEXTBOX);
- text_p.border_visible(false);
- text_p.rect(item_list_rect);
- text_p.follows.flags(FOLLOWS_ALL);
- addChild(LLUICtrlFactory::create<LLTextBox>(text_p));
-}
+ setCommitOnSelectionChange(true);
-// virtual
-void LLAvatarListTmp::draw()
-{
- LLFlatListView::draw();
- if (mHaveVolumeColumn)
- {
- updateVolume();
- }
+ // Set default sort order.
+ setComparator(&NAME_COMPARATOR);
}
-std::vector<LLUUID> LLAvatarListTmp::getSelectedIDs()
+void LLAvatarList::computeDifference(
+ const std::vector<LLUUID>& vnew_unsorted,
+ std::vector<LLUUID>& vadded,
+ std::vector<LLUUID>& vremoved)
{
- LLUUID selected_id;
- std::vector<LLUUID> avatar_ids;
+ std::vector<LLUUID> vcur;
+ std::vector<LLUUID> vnew = vnew_unsorted;
- getSelectedUUIDs(avatar_ids);
+ // Convert LLSDs to LLUUIDs.
+ {
+ std::vector<LLSD> vcur_values;
+ getValues(vcur_values);
- return avatar_ids;
-}
+ for (size_t i=0; i<vcur_values.size(); i++)
+ vcur.push_back(vcur_values[i].asUUID());
+ }
-void LLAvatarListTmp::addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos)
-{
- LLAvatarListItem* item = new LLAvatarListItem();
- item->showStatus(true);
- item->showInfoBtn(true);
- item->showSpeakingIndicator(true);
- item->setName(name);
- item->setAvatarId(id);
+ std::sort(vcur.begin(), vcur.end());
+ std::sort(vnew.begin(), vnew.end());
- item->childSetVisible("info_btn", false);
+ std::vector<LLUUID>::iterator it;
+ size_t maxsize = llmax(vcur.size(), vnew.size());
+ vadded.resize(maxsize);
+ vremoved.resize(maxsize);
- addItem(item, id, pos);
+ // what to remove
+ it = set_difference(vcur.begin(), vcur.end(), vnew.begin(), vnew.end(), vremoved.begin());
+ vremoved.erase(it, vremoved.end());
- setCommentVisible(false);
+ // what to add
+ it = set_difference(vnew.begin(), vnew.end(), vcur.begin(), vcur.end(), vadded.begin());
+ vadded.erase(it, vadded.end());
}
-BOOL LLAvatarListTmp::update(const std::vector<LLUUID>& all_buddies, const std::string& name_filter)
+BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::string& name_filter)
{
BOOL have_names = TRUE;
+ bool have_filter = name_filter != LLStringUtil::null;
// Save selection.
- std::vector<LLUUID> selected_ids = getSelectedIDs();
+ std::vector<LLUUID> selected_ids;
+ getSelectedUUIDs(selected_ids);
LLUUID current_id = getSelectedUUID();
- LLRect pos = getScrolledViewRect();
- std::vector<LLUUID>::const_iterator buddy_it = all_buddies.begin();
- clear();
- for(; buddy_it != all_buddies.end(); ++buddy_it)
+ // Determine what to add and what to remove.
+ std::vector<LLUUID> added, removed;
+ LLAvatarList::computeDifference(all_buddies, added, removed);
+
+ // Handle added items.
+ for (std::vector<LLUUID>::const_iterator it=added.begin(); it != added.end(); it++)
{
std::string name;
- const LLUUID& buddy_id = *buddy_it;
+ const LLUUID& buddy_id = *it;
have_names &= gCacheName->getFullName(buddy_id, name);
- if (name_filter != LLStringUtil::null && !findInsensitive(name, name_filter))
- continue;
+ if (!have_filter || findInsensitive(name, name_filter))
addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
}
+ // Handle removed items.
+ for (std::vector<LLUUID>::const_iterator it=removed.begin(); it != removed.end(); it++)
+ {
+ removeItemByUUID(*it);
+ }
+
+ // Handle filter.
+ if (have_filter)
+ {
+ std::vector<LLSD> cur_values;
+ getValues(cur_values);
+
+ for (std::vector<LLSD>::const_iterator it=cur_values.begin(); it != cur_values.end(); it++)
+ {
+ std::string name;
+ const LLUUID& buddy_id = it->asUUID();
+ have_names &= gCacheName->getFullName(buddy_id, name);
+ if (!findInsensitive(name, name_filter))
+ removeItemByUUID(buddy_id);
+ }
+ }
+
// Changed item in place, need to request sort and update columns
// because we might have changed data in a column on which the user
// has already sorted. JC
- // updateSort(); // TODO: implement sorting
+ sort();
// re-select items
// selectMultiple(selected_ids); // TODO: implement in LLFlatListView if need
selectItemByUUID(current_id);
- scrollToShowRect(pos);
-
-
- setCommentVisible(false);
-
- return have_names;
-}
-
-
-const LLUUID LLAvatarListTmp::getCurrentID() const
-{
- return getSelectedUUID();
+ // If the name filter is specified and the names are incomplete,
+ // we need to re-update when the names are complete so that
+ // the filter can be applied correctly.
+ //
+ // Otherwise, if we have no filter then no need to update again
+ // because the items will update their names.
+ return !have_filter || have_names;
}
-void LLAvatarListTmp::setCommentText(const std::string& comment_text)
+void LLAvatarList::sortByName()
{
- getChild<LLTextBox>(COMMENT_TEXTBOX)->setValue(comment_text);
+ setComparator(&NAME_COMPARATOR);
+ sort();
}
-
//////////////////////////////////////////////////////////////////////////
// PROTECTED SECTION
//////////////////////////////////////////////////////////////////////////
-
-// virtual overridden
-bool LLAvatarListTmp::removeItemPair(item_pair_t* item_pair)
+void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos)
{
- bool removed = LLFlatListView::removeItemPair(item_pair);
- setCommentVisible(size() == 0);
- return removed;
+ LLAvatarListItem* item = new LLAvatarListItem();
+ item->showStatus(false);
+ item->showInfoBtn(true);
+ item->showSpeakingIndicator(true);
+ item->setName(name);
+ item->setAvatarId(id);
+ item->setContextMenu(mContextMenu);
+
+ item->childSetVisible("info_btn", false);
+
+ addItem(item, id, pos);
}
-//////////////////////////////////////////////////////////////////////////
-// PRIVATE SECTION
-//////////////////////////////////////////////////////////////////////////
-// static
-std::string LLAvatarListTmp::getVolumeIcon(const LLUUID& id)
-{
- //
- // Determine icon appropriate for the current avatar volume.
- //
- // *TODO: remove this in favor of LLOutputMonitorCtrl
- // when ListView widget is implemented
- // which is capable of containing arbitrary widgets.
- //
- static LLOutputMonitorCtrl::Params default_monitor_params(LLUICtrlFactory::getDefaultParams<LLOutputMonitorCtrl>());
- bool muted = gVoiceClient->getIsModeratorMuted(id) || gVoiceClient->getOnMuteList(id);
- F32 power = gVoiceClient->getCurrentPower(id);
- std::string icon;
- if (muted)
- {
- icon = default_monitor_params.image_mute.name;
- }
- else if (power == 0.f)
- {
- icon = default_monitor_params.image_off.name;
- }
- else if (power < LLVoiceClient::OVERDRIVEN_POWER_LEVEL)
- {
- S32 icon_image_idx = llmin(2, llfloor((power / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 3.f));
- switch(icon_image_idx)
- {
- default:
- case 0:
- icon = default_monitor_params.image_on.name;
- break;
- case 1:
- icon = default_monitor_params.image_level_1.name;
- break;
- case 2:
- icon = default_monitor_params.image_level_2.name;
- break;
- }
- }
- else
+bool LLAvatarItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const
+{
+ const LLAvatarListItem* avatar_item1 = dynamic_cast<const LLAvatarListItem*>(item1);
+ const LLAvatarListItem* avatar_item2 = dynamic_cast<const LLAvatarListItem*>(item2);
+
+ if (!avatar_item1 || !avatar_item2)
{
- // overdriven
- icon = default_monitor_params.image_level_3.name;
+ llerror("item1 and item2 cannot be null", 0);
+ return true;
}
- return icon;
+ return doCompare(avatar_item1, avatar_item2);
}
-// Update volume column for all list rows.
-void LLAvatarListTmp::updateVolume()
+bool LLAvatarItemNameComparator::doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const
{
- // TODO: implement via Listener
- /*
- item_list& items = getItemList();
+ std::string name1 = avatar_item1->getAvatarName();
+ std::string name2 = avatar_item2->getAvatarName();
- for (item_list::iterator item_it = items.begin();
- item_it != items.end();
- ++item_it)
- {
- LLScrollListItem* itemp = (*item_it);
- LLUUID speaker_id = itemp->getUUID();
+ LLStringUtil::toUpper(name1);
+ LLStringUtil::toUpper(name2);
- LLScrollListCell* icon_cell = itemp->getColumn(COL_VOLUME);
- if (icon_cell)
- icon_cell->setValue(getVolumeIcon(speaker_id));
- }
- */
+ return name1 < name2;
}
-
-void LLAvatarListTmp::setCommentVisible(bool visible) const
-{
- getChildView(COMMENT_TEXTBOX)->setVisible(visible);
-}
-
-// EOF