summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
authorJames Cook <james@lindenlab.com>2010-03-08 10:54:23 -0800
committerJames Cook <james@lindenlab.com>2010-03-08 10:54:23 -0800
commit18ebacefcfb5909a58a213a97c6a687afe9b877e (patch)
tree5b48ebad64a253bd9aa50371c2308389cbec64bf /indra/llui
parent34d1d34ca100fd137c2a85f0e0f330730fb70aba (diff)
parent42606dbbb5f452211e4fc30ee0ed41334fc14e8d (diff)
Merge with viewer 2 beta 4
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/llcombobox.cpp2
-rw-r--r--indra/llui/llcombobox.h3
-rw-r--r--indra/llui/lltextbase.cpp47
-rw-r--r--indra/llui/lltextbase.h5
-rw-r--r--indra/llui/llurlentry.cpp109
-rw-r--r--indra/llui/llurlentry.h19
-rw-r--r--indra/llui/llurlregistry.cpp11
-rw-r--r--indra/llui/llurlregistry.h8
-rw-r--r--indra/llui/tests/llurlentry_stub.cpp19
-rw-r--r--indra/llui/tests/llurlentry_test.cpp1
10 files changed, 173 insertions, 51 deletions
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index ce25ee32b3..c693c18d1a 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -58,8 +58,6 @@
#include "lltooltip.h"
// Globals
-S32 LLCOMBOBOX_HEIGHT = 0;
-S32 LLCOMBOBOX_WIDTH = 0;
S32 MAX_COMBO_WIDTH = 500;
static LLDefaultChildRegistry::Register<LLComboBox> register_combo_box("combo_box");
diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h
index c694724248..7cac4cc738 100644
--- a/indra/llui/llcombobox.h
+++ b/indra/llui/llcombobox.h
@@ -49,9 +49,6 @@
class LLFontGL;
class LLViewBorder;
-extern S32 LLCOMBOBOX_HEIGHT;
-extern S32 LLCOMBOBOX_WIDTH;
-
class LLComboBox
: public LLUICtrl, public LLCtrlListInterface
{
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 851fb966ec..385812416d 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1527,6 +1527,20 @@ std::string LLTextBase::getText() const
return getViewModel()->getValue().asString();
}
+// IDEVO - icons can be UI image names or UUID sent from
+// server with avatar display name
+static LLUIImagePtr image_from_icon_name(const std::string& icon_name)
+{
+ if (LLUUID::validate(icon_name))
+ {
+ return LLUI::getUIImageByID( LLUUID(icon_name) );
+ }
+ else
+ {
+ return LLUI::getUIImage(icon_name);
+ }
+}
+
void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params)
{
LLStyle::Params style_params(input_params);
@@ -1539,7 +1553,7 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
LLUrlMatch match;
std::string text = new_text;
while ( LLUrlRegistry::instance().findUrl(text, match,
- boost::bind(&LLTextBase::replaceUrlLabel, this, _1, _2)) )
+ boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3)) )
{
start = match.getStart();
end = match.getEnd()+1;
@@ -1570,15 +1584,18 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
// output an optional icon before the Url
if (! match.getIcon().empty())
{
- LLUIImagePtr image = LLUI::getUIImage(match.getIcon());
+ LLUIImagePtr image = image_from_icon_name( match.getIcon() );
if (image)
{
- LLStyle::Params icon;
- icon.image = image;
+ LLStyle::Params icon_params;
+ icon_params.image = image;
+ // must refer to our link so we can update the icon later
+ // after name/group data is looked up
+ icon_params.link_href = match.getUrl();
// Text will be replaced during rendering with the icon,
// but string cannot be empty or the segment won't be
// added (or drawn).
- appendAndHighlightText(" ", prepend_newline, part, icon);
+ appendAndHighlightText(" ", prepend_newline, part, icon_params);
prepend_newline = false;
}
}
@@ -1728,8 +1745,9 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepen
}
-void LLTextBase::replaceUrlLabel(const std::string &url,
- const std::string &label)
+void LLTextBase::replaceUrl(const std::string &url,
+ const std::string &label,
+ const std::string &icon)
{
// get the full (wide) text for the editor so we can change it
LLWString text = getWText();
@@ -1759,6 +1777,21 @@ void LLTextBase::replaceUrlLabel(const std::string &url,
modified = true;
}
+ // Icon might be updated when more avatar or group info
+ // becomes available
+ if (style->isImage() && style->getLinkHREF() == url)
+ {
+ LLUIImagePtr image = image_from_icon_name( icon );
+ if (image)
+ {
+ LLStyle::Params icon_params;
+ icon_params.image = image;
+ LLStyleConstSP new_style(new LLStyle(icon_params));
+ seg->setStyle(new_style);
+ modified = true;
+ }
+ }
+
// work out the character offset for the next segment
seg_start = seg->getEnd();
}
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 5b24c63557..39cdaa0a58 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -313,7 +313,10 @@ protected:
// misc
void updateRects();
void needsScroll() { mScrollNeeded = TRUE; }
- void replaceUrlLabel(const std::string &url, const std::string &label);
+
+ // Replace a URL with a new icon and label, for example, when
+ // avatar names are looked up.
+ void replaceUrl(const std::string &url, const std::string &label, const std::string& icon);
protected:
// text segmentation and flow
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 35428e4227..ff6454c141 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -37,6 +37,7 @@
#include "llurlmatch.h"
#include "llurlregistry.h"
+#include "llavatarnamecache.h"
#include "llcachename.h"
#include "lltrans.h"
#include "lluicolortable.h"
@@ -56,6 +57,12 @@ std::string LLUrlEntryBase::getUrl(const std::string &string) const
return escapeUrl(string);
}
+//virtual
+std::string LLUrlEntryBase::getIcon(const std::string &url) const
+{
+ return mIcon;
+}
+
std::string LLUrlEntryBase::getIDStringFromUrl(const std::string &url) const
{
// return the id from a SLURL in the format /app/{cmd}/{id}/about
@@ -134,7 +141,9 @@ void LLUrlEntryBase::addObserver(const std::string &id,
}
}
-void LLUrlEntryBase::callObservers(const std::string &id, const std::string &label)
+void LLUrlEntryBase::callObservers(const std::string &id,
+ const std::string &label,
+ const std::string &icon)
{
// notify all callbacks waiting on the given uuid
std::multimap<std::string, LLUrlEntryObserver>::iterator it;
@@ -142,7 +151,7 @@ void LLUrlEntryBase::callObservers(const std::string &id, const std::string &lab
{
// call the callback - give it the new label
LLUrlEntryObserver &observer = it->second;
- (*observer.signal)(it->second.url, label);
+ (*observer.signal)(it->second.url, label, icon);
// then remove the signal - we only need to call it once
delete observer.signal;
mObservers.erase(it++);
@@ -314,13 +323,22 @@ LLUrlEntryAgent::LLUrlEntryAgent()
mColor = LLUIColorTable::instance().getColor("AgentLinkColor");
}
-void LLUrlEntryAgent::onAgentNameReceived(const LLUUID& id,
- const std::string& first,
- const std::string& last,
- BOOL is_group)
+void LLUrlEntryAgent::onNameCache(const LLUUID& id,
+ const std::string& full_name,
+ bool is_group)
{
+ callObservers(id.asString(), full_name, mIcon);
+}
+
+void LLUrlEntryAgent::onAvatarNameCache(const LLUUID& id,
+ const LLAvatarName& av_name)
+{
+ // IDEVO demo code
+ std::string label = av_name.mDisplayName + " (" + av_name.mSLID + ")";
+ // use custom icon if available
+ std::string icon = (!av_name.mBadge.empty() ? av_name.mBadge : mIcon);
// received the agent name from the server - tell our observers
- callObservers(id.asString(), first + " " + last);
+ callObservers(id.asString(), label, icon);
}
std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
@@ -330,34 +348,80 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa
// probably at the login screen, use short string for layout
return LLTrans::getString("LoadingData");
}
-
+
std::string agent_id_string = getIDStringFromUrl(url);
if (agent_id_string.empty())
{
// something went wrong, just give raw url
return unescapeUrl(url);
}
-
+
LLUUID agent_id(agent_id_string);
- std::string full_name;
if (agent_id.isNull())
{
return LLTrans::getString("AvatarNameNobody");
}
- else if (gCacheName->getFullName(agent_id, full_name))
+
+ if (LLAvatarNameCache::useDisplayNames())
{
- return full_name;
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(agent_id, &av_name))
+ {
+ return av_name.mDisplayName + " (" + av_name.mSLID + ")";
+ }
+ else
+ {
+ LLAvatarNameCache::get(agent_id,
+ boost::bind(&LLUrlEntryAgent::onAvatarNameCache,
+ this, _1, _2));
+ addObserver(agent_id_string, url, cb);
+ return LLTrans::getString("LoadingData");
+ }
}
else
{
- gCacheName->get(agent_id, FALSE,
- boost::bind(&LLUrlEntryAgent::onAgentNameReceived,
- this, _1, _2, _3, _4));
- addObserver(agent_id_string, url, cb);
- return LLTrans::getString("LoadingData");
+ // ...no display names
+ std::string full_name;
+ if (gCacheName->getFullName(agent_id, full_name))
+ {
+ return full_name;
+ }
+ else
+ {
+ gCacheName->get(agent_id, false,
+ boost::bind(&LLUrlEntryAgent::onNameCache,
+ this, _1, _2, _3));
+ addObserver(agent_id_string, url, cb);
+ return LLTrans::getString("LoadingData");
+ }
}
}
+
+std::string LLUrlEntryAgent::getIcon(const std::string &url) const
+{
+ std::string agent_id_string = getIDStringFromUrl(url);
+ if (agent_id_string.empty())
+ {
+ return mIcon;
+ }
+
+ LLUUID agent_id(agent_id_string);
+ if (agent_id.isNull())
+ {
+ return mIcon;
+ }
+
+ LLAvatarName av_name;
+ LLAvatarNameCache::get(agent_id, &av_name);
+ if (av_name.mBadge.empty())
+ {
+ return mIcon;
+ }
+
+ return av_name.mBadge;
+}
+
//
// LLUrlEntryGroup Describes a Second Life group Url, e.g.,
// secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about
@@ -374,12 +438,11 @@ LLUrlEntryGroup::LLUrlEntryGroup()
}
void LLUrlEntryGroup::onGroupNameReceived(const LLUUID& id,
- const std::string& first,
- const std::string& last,
- BOOL is_group)
+ const std::string& name,
+ bool is_group)
{
// received the group name from the server - tell our observers
- callObservers(id.asString(), first);
+ callObservers(id.asString(), name, mIcon);
}
std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
@@ -409,9 +472,9 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa
}
else
{
- gCacheName->get(group_id, TRUE,
+ gCacheName->get(group_id, true,
boost::bind(&LLUrlEntryGroup::onGroupNameReceived,
- this, _1, _2, _3, _4));
+ this, _1, _2, _3));
addObserver(group_id_string, url, cb);
return LLTrans::getString("LoadingData");
}
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index c947ef7259..c2cbe4d4c8 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -41,8 +41,11 @@
#include <string>
#include <map>
+class LLAvatarName;
+
typedef boost::signals2::signal<void (const std::string& url,
- const std::string& label)> LLUrlLabelSignal;
+ const std::string& label,
+ const std::string& icon)> LLUrlLabelSignal;
typedef LLUrlLabelSignal::slot_type LLUrlLabelCallback;
///
@@ -77,7 +80,7 @@ public:
virtual std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) { return url; }
/// Return an icon that can be displayed next to Urls of this type
- std::string getIcon() const { return mIcon; }
+ virtual std::string getIcon(const std::string &url) const;
/// Return the color to render the displayed text
LLUIColor getColor() const { return mColor; }
@@ -101,7 +104,7 @@ protected:
std::string getLabelFromWikiLink(const std::string &url) const;
std::string getUrlFromWikiLink(const std::string &string) const;
void addObserver(const std::string &id, const std::string &url, const LLUrlLabelCallback &cb);
- void callObservers(const std::string &id, const std::string &label);
+ void callObservers(const std::string &id, const std::string &label, const std::string& icon);
typedef struct {
std::string url;
@@ -163,15 +166,16 @@ public:
///
/// LLUrlEntryAgent Describes a Second Life agent Url, e.g.,
/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
-///
class LLUrlEntryAgent : public LLUrlEntryBase
{
public:
LLUrlEntryAgent();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+ /*virtual*/ std::string getIcon(const std::string &url) const;
+
private:
- void onAgentNameReceived(const LLUUID& id, const std::string& first,
- const std::string& last, BOOL is_group);
+ void onNameCache(const LLUUID& id, const std::string& full_name, bool is_group);
+ void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name);
};
///
@@ -184,8 +188,7 @@ public:
LLUrlEntryGroup();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
private:
- void onGroupNameReceived(const LLUUID& id, const std::string& first,
- const std::string& last, BOOL is_group);
+ void onGroupNameReceived(const LLUUID& id, const std::string& name, bool is_group);
};
///
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index faa02e1904..3fadf3dd11 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -37,12 +37,14 @@
#include <boost/regex.hpp>
// default dummy callback that ignores any label updates from the server
-void LLUrlRegistryNullCallback(const std::string &url, const std::string &label)
+void LLUrlRegistryNullCallback(const std::string &url, const std::string &label, const std::string& icon)
{
}
LLUrlRegistry::LLUrlRegistry()
{
+ mUrlEntry.reserve(16);
+
// Urls are matched in the order that they were registered
registerUrl(new LLUrlEntryNoLink());
registerUrl(new LLUrlEntrySLURL());
@@ -74,10 +76,13 @@ LLUrlRegistry::~LLUrlRegistry()
}
}
-void LLUrlRegistry::registerUrl(LLUrlEntryBase *url)
+void LLUrlRegistry::registerUrl(LLUrlEntryBase *url, bool force_front)
{
if (url)
{
+ if (force_front) // IDEVO
+ mUrlEntry.insert(mUrlEntry.begin(), url);
+ else
mUrlEntry.push_back(url);
}
}
@@ -175,7 +180,7 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
match_entry->getUrl(url),
match_entry->getLabel(url, cb),
match_entry->getTooltip(url),
- match_entry->getIcon(),
+ match_entry->getIcon(url),
match_entry->getColor(),
match_entry->getMenuName(),
match_entry->getLocation(url),
diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h
index 399ee0a988..dffbd9d4bf 100644
--- a/indra/llui/llurlregistry.h
+++ b/indra/llui/llurlregistry.h
@@ -43,7 +43,9 @@
#include <vector>
/// This default callback for findUrl() simply ignores any label updates
-void LLUrlRegistryNullCallback(const std::string &url, const std::string &label);
+void LLUrlRegistryNullCallback(const std::string &url,
+ const std::string &label,
+ const std::string &icon);
///
/// LLUrlRegistry is a singleton that contains a set of Url types that
@@ -70,7 +72,9 @@ public:
~LLUrlRegistry();
/// add a new Url handler to the registry (will be freed on destruction)
- void registerUrl(LLUrlEntryBase *url);
+ /// optionally force it to the front of the list, making it take
+ /// priority over other regular expression matches for URLs
+ void registerUrl(LLUrlEntryBase *url, bool force_front = false);
/// get the next Url in an input string, starting at a given character offset
/// your callback is invoked if the matched Url's label changes in the future
diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp
index 26d1f2e067..e984f5cf81 100644
--- a/indra/llui/tests/llurlentry_stub.cpp
+++ b/indra/llui/tests/llurlentry_stub.cpp
@@ -22,11 +22,28 @@
#include "llstring.h"
#include "llfile.h"
+#include "llavatarnamecache.h"
#include "llcachename.h"
#include "lluuid.h"
#include <string>
+// Stub for LLAvatarNameCache
+bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
+{
+ return false;
+}
+
+void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
+{
+ return;
+}
+
+bool LLAvatarNameCache::useDisplayNames()
+{
+ return false;
+}
+
//
// Stub implementation for LLCacheName
//
@@ -42,7 +59,7 @@ BOOL LLCacheName::getGroupName(const LLUUID& id, std::string& group)
return TRUE;
}
-boost::signals2::connection LLCacheName::get(const LLUUID& id, BOOL is_group, const LLCacheNameCallback& callback)
+boost::signals2::connection LLCacheName::get(const LLUUID& id, bool is_group, const LLCacheNameCallback& callback)
{
return boost::signals2::connection();
}
diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp
index cbb303a059..bcb1e65092 100644
--- a/indra/llui/tests/llurlentry_test.cpp
+++ b/indra/llui/tests/llurlentry_test.cpp
@@ -285,7 +285,6 @@ namespace tut
testRegex("Agent Url alternate command", url,
"XXX secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar",
"secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar");
-
}
template<> template<>