diff options
author | Steven Bennetts <steve@lindenlab.com> | 2009-09-29 19:37:05 +0000 |
---|---|---|
committer | Steven Bennetts <steve@lindenlab.com> | 2009-09-29 19:37:05 +0000 |
commit | 606b381c9fbc43c214afd26fb2e2598eec656b66 (patch) | |
tree | 422a6d5d94d50bd97ac5bcbdb52f0f6de083c6e7 /indra/newview/llavatarlist.cpp | |
parent | 751cc7cf68bb4d766e8ecaaf76af054dcfbbe9dc (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.cpp | 506 |
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 |