WIP: critical bug EXT-4837 ([NUX] When filter results in null state, provide a message suggesting the user try global search.)

Partial implementation of help text in case of empty list when filtered for Nearby and Recent lists of People panel:
 * Extracted support implementation of several messages for empty list depend of filtering from LLGroupList to LLFlatListEx
 * change inheritence of LLGroupList and LLAvatarList from LLFlatListView to LLFlatListViewEx
 * updated panel people to init Nearby & Recent lists with appropriate messages.

--HG--
branch : product-engine
master
Mike Antipov 2010-04-21 10:17:09 +03:00
parent 5ecd9db845
commit 4395d8e9f1
8 changed files with 116 additions and 55 deletions

View File

@ -1,10 +1,10 @@
/**
* @file llflatlistview.cpp
* @brief LLFlatListView base class
* @brief LLFlatListView base class and extension to support messages for several cases of an empty list.
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
* Copyright (c) 2009-2010, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@ -1122,4 +1122,38 @@ void LLFlatListView::detachItems(std::vector<LLPanel*>& detached_items)
}
}
/************************************************************************/
/* LLFlatListViewEx implementation */
/************************************************************************/
LLFlatListViewEx::Params::Params()
: no_items_msg("no_items_msg")
, no_filtered_items_msg("no_filtered_items_msg")
{
}
LLFlatListViewEx::LLFlatListViewEx(const Params& p)
: LLFlatListView(p)
, mNoFilteredItemsMsg(p.no_filtered_items_msg)
, mNoItemsMsg(p.no_items_msg)
{
}
void LLFlatListViewEx::updateNoItemsMessage(bool items_filtered)
{
if (items_filtered)
{
// items were filtered
setNoItemsCommentText(mNoFilteredItemsMsg);
}
else
{
// list does not contain any items at all
setNoItemsCommentText(mNoItemsMsg);
}
}
//EOF

View File

@ -1,10 +1,10 @@
/**
* @file llflatlistview.h
* @brief LLFlatListView base class
* @brief LLFlatListView base class and extension to support messages for several cases of an empty list.
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
* Copyright (c) 2009-2010, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@ -430,4 +430,54 @@ private:
commit_signal_t mOnReturnSignal;
};
/**
* Extends LLFlatListView functionality to show different messages when there are no items in the
* list depend on whether they are filtered or not.
*
* Class provides one message per case of empty list.
* It also provides protected updateNoItemsMessage() method to be called each time when derived list
* is changed to update base mNoItemsCommentTextbox value.
*
* It is implemented to avoid duplication of this functionality in concrete implementations of the
* lists. It is intended to be used as a base class for lists which should support two different
* messages for empty state. Can be improved to support more than two messages via state-to-message map.
*/
class LLFlatListViewEx : public LLFlatListView
{
public:
struct Params : public LLInitParam::Block<Params, LLFlatListView::Params>
{
/**
* Contains a message for empty list when it does not contain any items at all.
*/
Optional<std::string> no_items_msg;
/**
* Contains a message for empty list when its items are removed by filtering.
*/
Optional<std::string> no_filtered_items_msg;
Params();
};
// *WORKAROUND: two methods to overload appropriate Params due to localization issue:
// no_items_msg & no_filtered_items_msg attributes are not defined as translatable in VLT. See EXT-5931
void setNoItemsMsg(const std::string& msg) { mNoItemsMsg = msg; }
void setNoFilteredItemsMsg(const std::string& msg) { mNoFilteredItemsMsg = msg; }
protected:
LLFlatListViewEx(const Params& p);
/**
* Applies a message for empty list depend on passed argument.
*
* @param items_filtered - if true message for filtered items will be set, otherwise for
* completely empty list.
*/
void updateNoItemsMessage(bool items_filtered);
private:
std::string mNoFilteredItemsMsg;
std::string mNoItemsMsg;
};
#endif

View File

@ -113,7 +113,7 @@ LLAvatarList::Params::Params()
}
LLAvatarList::LLAvatarList(const Params& p)
: LLFlatListView(p)
: LLFlatListViewEx(p)
, mIgnoreOnlineStatus(p.ignore_online_status)
, mShowLastInteractionTime(p.show_last_interaction_time)
, mContextMenu(NULL)
@ -154,7 +154,7 @@ void LLAvatarList::draw()
// *NOTE dzaporozhan
// Call refresh() after draw() to avoid flickering of avatar list items.
LLFlatListView::draw();
LLFlatListViewEx::draw();
if (mDirty)
refresh();
@ -171,7 +171,7 @@ void LLAvatarList::clear()
{
getIDs().clear();
setDirty(true);
LLFlatListView::clear();
LLFlatListViewEx::clear();
}
void LLAvatarList::setNameFilter(const std::string& filter)
@ -179,6 +179,10 @@ void LLAvatarList::setNameFilter(const std::string& filter)
if (mNameFilter != filter)
{
mNameFilter = filter;
// update message for empty state here instead of refresh() to avoid blinking when switch
// between tabs.
updateNoItemsMessage(!mNameFilter.empty());
setDirty();
}
}
@ -360,7 +364,7 @@ S32 LLAvatarList::notifyParent(const LLSD& info)
sort();
return 1;
}
return LLFlatListView::notifyParent(info);
return LLFlatListViewEx::notifyParent(info);
}
void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_online, EAddPosition pos)

View File

@ -49,11 +49,11 @@ class LLTimer;
* @see setDirty()
* @see setNameFilter()
*/
class LLAvatarList : public LLFlatListView
class LLAvatarList : public LLFlatListViewEx
{
LOG_CLASS(LLAvatarList);
public:
struct Params : public LLInitParam::Block<Params, LLFlatListView::Params>
struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params>
{
Optional<bool> ignore_online_status, // show all items as online
show_last_interaction_time, // show most recent interaction time. *HACK: move this to a derived class

View File

@ -71,18 +71,10 @@ public:
static const LLGroupComparator GROUP_COMPARATOR;
LLGroupList::Params::Params()
: no_groups_msg("no_groups_msg")
, no_filtered_groups_msg("no_filtered_groups_msg")
{
}
LLGroupList::LLGroupList(const Params& p)
: LLFlatListView(p)
: LLFlatListViewEx(p)
, mDirty(true) // to force initial update
, mNoFilteredGroupsMsg(p.no_filtered_groups_msg)
, mNoGroupsMsg(p.no_groups_msg)
{
// Listen for agent group changes.
gAgent.addListener(this, "new group");
@ -160,16 +152,7 @@ void LLGroupList::refresh()
bool have_filter = !mNameFilter.empty();
// set no items message depend on filter state & total count of groups
if (have_filter)
{
// groups were filtered
setNoItemsCommentText(mNoFilteredGroupsMsg);
}
else if (0 == count)
{
// user is not a member of any group
setNoItemsCommentText(mNoGroupsMsg);
}
updateNoItemsMessage(have_filter);
clear();

View File

@ -47,23 +47,10 @@
*
* @see setNameFilter()
*/
class LLGroupList: public LLFlatListView, public LLOldEvents::LLSimpleListener
class LLGroupList: public LLFlatListViewEx, public LLOldEvents::LLSimpleListener
{
LOG_CLASS(LLGroupList);
public:
struct Params : public LLInitParam::Block<Params, LLFlatListView::Params>
{
/**
* Contains a message for empty list when user is not a member of any group
*/
Optional<std::string> no_groups_msg;
/**
* Contains a message for empty list when all groups don't match passed filter
*/
Optional<std::string> no_filtered_groups_msg;
Params();
};
LLGroupList(const Params& p);
virtual ~LLGroupList();
@ -75,11 +62,6 @@ public:
void toggleIcons();
bool getIconsVisible() const { return mShowIcons; }
// *WORKAROUND: two methods to overload appropriate Params due to localization issue:
// no_groups_msg & no_filtered_groups_msg attributes are not defined as translatable in VLT. See EXT-5931
void setNoGroupsMsg(const std::string& msg) { mNoGroupsMsg = msg; }
void setNoFilteredGroupsMsg(const std::string& msg) { mNoFilteredGroupsMsg = msg; }
private:
void setDirty(bool val = true) { mDirty = val; }
void refresh();
@ -94,8 +76,6 @@ private:
bool mShowIcons;
bool mDirty;
std::string mNameFilter;
std::string mNoFilteredGroupsMsg;
std::string mNoGroupsMsg;
};
class LLButton;

View File

@ -512,15 +512,19 @@ BOOL LLPanelPeople::postBuild()
mNearbyList = getChild<LLPanel>(NEARBY_TAB_NAME)->getChild<LLAvatarList>("avatar_list");
mNearbyList->setNoItemsCommentText(getString("no_one_near"));
mNearbyList->setNoItemsMsg(getString("no_one_near"));
mNearbyList->setNoFilteredItemsMsg(getString("no_one_filtered_near"));
mNearbyList->setShowIcons("NearbyListShowIcons");
mRecentList = getChild<LLPanel>(RECENT_TAB_NAME)->getChild<LLAvatarList>("avatar_list");
mRecentList->setNoItemsCommentText(getString("no_people"));
mRecentList->setNoItemsCommentText(getString("no_recent_people"));
mRecentList->setNoItemsMsg(getString("no_recent_people"));
mRecentList->setNoFilteredItemsMsg(getString("no_filtered_recent_people"));
mRecentList->setShowIcons("RecentListShowIcons");
mGroupList = getChild<LLGroupList>("group_list");
mGroupList->setNoGroupsMsg(getString("no_groups_msg"));
mGroupList->setNoFilteredGroupsMsg(getString("no_filtered_groups_msg"));
mGroupList->setNoItemsMsg(getString("no_groups_msg"));
mGroupList->setNoFilteredItemsMsg(getString("no_filtered_groups_msg"));
mNearbyList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
mRecentList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);

View File

@ -12,11 +12,17 @@
top="0"
width="333">
<string
name="no_people"
name="no_recent_people"
value="No recent people. Looking for people to hang out with? Try [secondlife:///app/search/people Search] or the [secondlife:///app/worldmap World Map]." />
<string
name="no_filtered_recent_people"
value="Didn't find what you're looking for? Try [secondlife:///app/search/people Search]." />
<string
name="no_one_near"
value="No one nearby. Looking for people to hang out with? Try [secondlife:///app/search/people Search] or the [secondlife:///app/worldmap World Map]." />
<string
name="no_one_filtered_near"
value="Didn't find what you're looking for? Try [secondlife:///app/search/people Search]." />
<string
name="no_friends_online"
value="No friends online" />
@ -30,7 +36,7 @@
name="groups_filter_label"
value="Filter Groups" />
<!--
*WORKAROUND: for group_list.no_groups_msg & group_list.no_filtered_groups_msg attributes.
*WORKAROUND: for group_list.no_items_msg & group_list.no_filtered_items_msg attributes.
They are not defined as translatable in VLT. See EXT-5931
-->
<string