summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BuildParams12
-rw-r--r--indra/llcommon/llinstancetracker.h5
-rw-r--r--indra/llcommon/llrefcount.h19
-rw-r--r--indra/llcommon/llthread.h17
-rw-r--r--indra/llui/llloadingindicator.cpp2
-rw-r--r--indra/llui/llloadingindicator.h6
-rw-r--r--indra/llui/llmenubutton.cpp78
-rw-r--r--indra/llui/llmenubutton.h11
-rw-r--r--indra/llui/llmenugl.cpp5
-rw-r--r--indra/llui/llmenugl.h2
-rw-r--r--indra/llui/llnotifications.cpp135
-rw-r--r--indra/llui/llnotifications.h74
-rw-r--r--indra/llui/llnotificationslistener.cpp8
-rw-r--r--indra/llui/llnotificationtemplate.h24
-rw-r--r--indra/llui/llsdparam.cpp6
-rw-r--r--indra/llui/llui.cpp212
-rw-r--r--indra/llui/llui.h11
-rw-r--r--indra/llui/lluiimage.cpp48
-rw-r--r--indra/llui/lluiimage.h8
-rw-r--r--indra/llui/tests/llurlentry_stub.cpp18
-rw-r--r--indra/llui/tests/llurlmatch_test.cpp18
-rw-r--r--indra/llxuixml/llinitparam.cpp59
-rw-r--r--indra/llxuixml/llinitparam.h1451
-rw-r--r--indra/llxuixml/llxuiparser.cpp80
-rw-r--r--indra/llxuixml/llxuiparser.h2
-rw-r--r--indra/newview/CMakeLists.txt2
-rwxr-xr-xindra/newview/llavataractions.cpp26
-rw-r--r--indra/newview/llavataractions.h10
-rw-r--r--indra/newview/llbrowsernotification.cpp5
-rw-r--r--indra/newview/llchathistory.cpp3
-rw-r--r--indra/newview/llchiclet.cpp33
-rw-r--r--indra/newview/llchiclet.h31
-rw-r--r--indra/newview/llfloaternotificationsconsole.cpp38
-rw-r--r--indra/newview/llfloateroutbox.cpp59
-rw-r--r--indra/newview/llfloateroutbox.h2
-rwxr-xr-xindra/newview/llfloaterpreference.cpp3
-rw-r--r--indra/newview/llfloatersidepanelcontainer.cpp7
-rw-r--r--indra/newview/llfloatervoicevolume.cpp209
-rw-r--r--indra/newview/llfloatervoicevolume.h35
-rw-r--r--indra/newview/llfolderview.cpp23
-rw-r--r--indra/newview/llfolderview.h8
-rw-r--r--indra/newview/llfolderviewitem.cpp5
-rw-r--r--indra/newview/llfollowcam.cpp1
-rw-r--r--indra/newview/llhudnametag.cpp282
-rw-r--r--indra/newview/llhudnametag.h2
-rw-r--r--indra/newview/llhudobject.cpp2
-rw-r--r--indra/newview/llhudobject.h2
-rw-r--r--indra/newview/llimhandler.cpp30
-rw-r--r--indra/newview/llinspectavatar.cpp577
-rw-r--r--indra/newview/lllistcontextmenu.h2
-rw-r--r--indra/newview/llnearbychathandler.cpp8
-rw-r--r--indra/newview/llnearbychathandler.h3
-rw-r--r--indra/newview/llnotificationalerthandler.cpp45
-rw-r--r--indra/newview/llnotificationgrouphandler.cpp59
-rw-r--r--indra/newview/llnotificationhandler.h184
-rw-r--r--indra/newview/llnotificationhandlerutil.cpp158
-rw-r--r--indra/newview/llnotificationhinthandler.cpp26
-rw-r--r--indra/newview/llnotificationmanager.cpp98
-rw-r--r--indra/newview/llnotificationmanager.h17
-rw-r--r--indra/newview/llnotificationofferhandler.cpp86
-rw-r--r--indra/newview/llnotificationscripthandler.cpp50
-rw-r--r--indra/newview/llnotificationtiphandler.cpp36
-rw-r--r--indra/newview/lloutputmonitorctrl.cpp12
-rw-r--r--indra/newview/lloutputmonitorctrl.h1
-rw-r--r--indra/newview/llpanelblockedlist.cpp16
-rw-r--r--indra/newview/llpanelblockedlist.h1
-rw-r--r--indra/newview/llpanelobjectinventory.cpp43
-rw-r--r--indra/newview/llpanelpeople.cpp324
-rw-r--r--indra/newview/llpanelpeople.h31
-rw-r--r--indra/newview/llpreviewscript.cpp6
-rw-r--r--indra/newview/llscreenchannel.cpp49
-rw-r--r--indra/newview/llscreenchannel.h14
-rw-r--r--indra/newview/llspatialpartition.cpp4
-rw-r--r--indra/newview/llsyswellwindow.cpp40
-rw-r--r--indra/newview/llsyswellwindow.h19
-rw-r--r--indra/newview/lltoastgroupnotifypanel.cpp2
-rw-r--r--indra/newview/lltoastgroupnotifypanel.h5
-rw-r--r--indra/newview/lltoastnotifypanel.cpp4
-rw-r--r--indra/newview/lltoastnotifypanel.h4
-rw-r--r--indra/newview/lltoastscripttextbox.h2
-rw-r--r--indra/newview/llviewerfloaterreg.cpp2
-rw-r--r--indra/newview/llviewermenu.cpp9
-rwxr-xr-xindra/newview/llviewermessage.cpp6
-rwxr-xr-xindra/newview/llviewerwindow.cpp25
-rw-r--r--indra/newview/llvoavatar.cpp962
-rw-r--r--indra/newview/llvoavatar.h15
-rw-r--r--indra/newview/llvoicevisualizer.cpp1267
-rw-r--r--indra/newview/llvoicevisualizer.h37
-rw-r--r--indra/newview/pipeline.cpp7
-rw-r--r--indra/newview/skins/default/xui/en/floater_people.xml12
-rw-r--r--indra/newview/skins/default/xui/en/floater_voice_volume.xml59
-rw-r--r--indra/newview/skins/default/xui/en/inspect_avatar.xml114
-rw-r--r--indra/newview/skins/default/xui/en/menu_group_plus.xml4
-rw-r--r--indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml143
-rw-r--r--indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml252
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_friends_view.xml (renamed from indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml)4
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_groups.xml4
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_groups_view.xml (renamed from indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml)9
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_nearby_view.xml53
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml57
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_recent_view.xml (renamed from indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml)4
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml22
-rw-r--r--indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml5
-rw-r--r--indra/newview/skins/default/xui/en/panel_people.xml912
104 files changed, 3893 insertions, 5146 deletions
diff --git a/BuildParams b/BuildParams
index 1c39dd7cc7..84e51e1442 100644
--- a/BuildParams
+++ b/BuildParams
@@ -111,6 +111,18 @@ viewer-mesh.login_channel = "Project Viewer - Mesh"
viewer-mesh.viewer_grid = aditi
viewer-mesh.email = shining@lists.lindenlab.com
+# ========================================
+# viewer-chui
+#
+# ========================================
+
+viewer-chui.viewer_channel = "Project Viewer - CHUI"
+viewer-chui.login_channel = "Project Viewer - CHUI"
+viewer-chui.viewer_grid = agni
+viewer-chui.build_debug_release_separately = true
+viewer-chui.build_CYGWIN_Debug = false
+viewer-chui.build_viewer_update_version_manager = false
+
# ================
# oz
# ================
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index 34d841a4e0..11f582372e 100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -43,7 +43,7 @@
* semantics: one instance per process, rather than one instance per module as
* sometimes happens with data simply declared static.
*/
-class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable
+class LL_COMMON_API LLInstanceTrackerBase
{
protected:
/// Get a process-unique void* pointer slot for the specified type_info
@@ -209,6 +209,9 @@ protected:
virtual const KEY& getKey() const { return mInstanceKey; }
private:
+ LLInstanceTracker( const LLInstanceTracker& );
+ const LLInstanceTracker& operator=( const LLInstanceTracker& );
+
void add_(KEY key)
{
mInstanceKey = key;
diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h
index 8eb5d53f3f..32ae15435a 100644
--- a/indra/llcommon/llrefcount.h
+++ b/indra/llcommon/llrefcount.h
@@ -27,6 +27,7 @@
#define LLREFCOUNT_H
#include <boost/noncopyable.hpp>
+#include <boost/intrusive_ptr.hpp>
#define LL_REF_COUNT_DEBUG 0
#if LL_REF_COUNT_DEBUG
@@ -86,4 +87,22 @@ private:
#endif
};
+/**
+ * intrusive pointer support
+ * this allows you to use boost::intrusive_ptr with any LLRefCount-derived type
+ */
+namespace boost
+{
+ inline void intrusive_ptr_add_ref(LLRefCount* p)
+ {
+ p->ref();
+ }
+
+ inline void intrusive_ptr_release(LLRefCount* p)
+ {
+ p->unref();
+ }
+};
+
+
#endif
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index b52e70ab2e..cf39696b4f 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -30,6 +30,7 @@
#include "llapp.h"
#include "llapr.h"
#include "apr_thread_cond.h"
+#include "boost/intrusive_ptr.hpp"
class LLThread;
class LLMutex;
@@ -266,6 +267,22 @@ private:
S32 mRef;
};
+/**
+ * intrusive pointer support for LLThreadSafeRefCount
+ * this allows you to use boost::intrusive_ptr with any LLThreadSafeRefCount-derived type
+ */
+namespace boost
+{
+ inline void intrusive_ptr_add_ref(LLThreadSafeRefCount* p)
+ {
+ p->ref();
+ }
+
+ inline void intrusive_ptr_release(LLThreadSafeRefCount* p)
+ {
+ p->unref();
+ }
+};
//============================================================================
// Simple responder for self destructing callbacks
diff --git a/indra/llui/llloadingindicator.cpp b/indra/llui/llloadingindicator.cpp
index 6ac38f5ad4..1ede5b706f 100644
--- a/indra/llui/llloadingindicator.cpp
+++ b/indra/llui/llloadingindicator.cpp
@@ -52,7 +52,7 @@ LLLoadingIndicator::LLLoadingIndicator(const Params& p)
void LLLoadingIndicator::initFromParams(const Params& p)
{
- BOOST_FOREACH(LLUIImage* image, p.images.image)
+ BOOST_FOREACH(LLUIImage* image, p.images().image)
{
mImages.push_back(image);
}
diff --git a/indra/llui/llloadingindicator.h b/indra/llui/llloadingindicator.h
index c1f979c111..ffcb329f42 100644
--- a/indra/llui/llloadingindicator.h
+++ b/indra/llui/llloadingindicator.h
@@ -51,7 +51,7 @@ class LLLoadingIndicator
LOG_CLASS(LLLoadingIndicator);
public:
- struct Images : public LLInitParam::BatchBlock<Images>
+ struct Images : public LLInitParam::Block<Images>
{
Multiple<LLUIImage*> image;
@@ -62,8 +62,8 @@ public:
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
- Optional<F32> images_per_sec;
- Optional<Images> images;
+ Optional<F32> images_per_sec;
+ Optional<Atomic<Images> > images;
Params()
: images_per_sec("images_per_sec", 1.0f),
diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp
index 50d59f79f4..746ade4648 100644
--- a/indra/llui/llmenubutton.cpp
+++ b/indra/llui/llmenubutton.cpp
@@ -44,33 +44,27 @@ void LLMenuButton::MenuPositions::declareValues()
LLMenuButton::Params::Params()
: menu_filename("menu_filename"),
- position("position", MP_BOTTOM_LEFT)
+ position("menu_position", MP_BOTTOM_LEFT)
{
+ addSynonym(position, "position");
}
LLMenuButton::LLMenuButton(const LLMenuButton::Params& p)
: LLButton(p),
mIsMenuShown(false),
- mMenuPosition(p.position)
+ mMenuPosition(p.position),
+ mOwnMenu(false)
{
std::string menu_filename = p.menu_filename;
- if (!menu_filename.empty())
- {
- LLToggleableMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(menu_filename, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
- if (!menu)
- {
- llwarns << "Error loading menu_button menu" << llendl;
- return;
- }
-
- menu->setVisibilityChangeCallback(boost::bind(&LLMenuButton::onMenuVisibilityChange, this, _2));
-
- mMenuHandle = menu->getHandle();
+ setMenu(menu_filename, mMenuPosition);
+ updateMenuOrigin();
+}
- updateMenuOrigin();
- }
+LLMenuButton::~LLMenuButton()
+{
+ cleanup();
}
boost::signals2::connection LLMenuButton::setMouseDownCallback( const mouse_signal_t::slot_type& cb )
@@ -80,9 +74,7 @@ boost::signals2::connection LLMenuButton::setMouseDownCallback( const mouse_sign
void LLMenuButton::hideMenu()
{
- if(mMenuHandle.isDead()) return;
-
- LLToggleableMenu* menu = dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
+ LLToggleableMenu* menu = getMenu();
if (menu)
{
menu->setVisible(FALSE);
@@ -94,19 +86,39 @@ LLToggleableMenu* LLMenuButton::getMenu()
return dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
}
-void LLMenuButton::setMenu(LLToggleableMenu* menu, EMenuPosition position /*MP_TOP_LEFT*/)
+void LLMenuButton::setMenu(const std::string& menu_filename, EMenuPosition position /*MP_TOP_LEFT*/)
+{
+ if (menu_filename.empty())
+ {
+ return;
+ }
+
+ LLToggleableMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(menu_filename, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
+ if (!menu)
+ {
+ llwarns << "Error loading menu_button menu" << llendl;
+ return;
+ }
+
+ setMenu(menu, position, true);
+}
+
+void LLMenuButton::setMenu(LLToggleableMenu* menu, EMenuPosition position /*MP_TOP_LEFT*/, bool take_ownership /*false*/)
{
if (!menu) return;
+ cleanup(); // destroy the previous memnu if we own it
+
mMenuHandle = menu->getHandle();
mMenuPosition = position;
+ mOwnMenu = take_ownership;
menu->setVisibilityChangeCallback(boost::bind(&LLMenuButton::onMenuVisibilityChange, this, _2));
}
BOOL LLMenuButton::handleKeyHere(KEY key, MASK mask )
{
- if (mMenuHandle.isDead()) return FALSE;
+ if (!getMenu()) return FALSE;
if( KEY_RETURN == key && mask == MASK_NONE && !gKeyboard->getKeyRepeated(key))
{
@@ -118,7 +130,7 @@ BOOL LLMenuButton::handleKeyHere(KEY key, MASK mask )
return TRUE;
}
- LLToggleableMenu* menu = dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
+ LLToggleableMenu* menu = getMenu();
if (menu && menu->getVisible() && key == KEY_ESCAPE && mask == MASK_NONE)
{
menu->setVisible(FALSE);
@@ -139,9 +151,12 @@ BOOL LLMenuButton::handleMouseDown(S32 x, S32 y, MASK mask)
void LLMenuButton::toggleMenu()
{
- if(mMenuHandle.isDead()) return;
+ if (mValidateSignal && !(*mValidateSignal)(this, LLSD()))
+ {
+ return;
+ }
- LLToggleableMenu* menu = dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
+ LLToggleableMenu* menu = getMenu();
if (!menu) return;
// Store the button rectangle to toggle menu visibility if a mouse event
@@ -170,7 +185,8 @@ void LLMenuButton::toggleMenu()
void LLMenuButton::updateMenuOrigin()
{
- if (mMenuHandle.isDead()) return;
+ LLToggleableMenu* menu = getMenu();
+ if (!menu) return;
LLRect rect = getRect();
@@ -179,12 +195,12 @@ void LLMenuButton::updateMenuOrigin()
case MP_TOP_LEFT:
{
mX = rect.mLeft;
- mY = rect.mTop + mMenuHandle.get()->getRect().getHeight();
+ mY = rect.mTop + menu->getRect().getHeight();
break;
}
case MP_TOP_RIGHT:
{
- const LLRect& menu_rect = mMenuHandle.get()->getRect();
+ const LLRect& menu_rect = menu->getRect();
mX = rect.mRight - menu_rect.getWidth();
mY = rect.mTop + menu_rect.getHeight();
break;
@@ -211,3 +227,11 @@ void LLMenuButton::onMenuVisibilityChange(const LLSD& param)
mIsMenuShown = false;
}
}
+
+void LLMenuButton::cleanup()
+{
+ if (mMenuHandle.get() && mOwnMenu)
+ {
+ mMenuHandle.get()->die();
+ }
+}
diff --git a/indra/llui/llmenubutton.h b/indra/llui/llmenubutton.h
index e2396e7fb2..67ec1983b3 100644
--- a/indra/llui/llmenubutton.h
+++ b/indra/llui/llmenubutton.h
@@ -34,6 +34,8 @@ class LLToggleableMenu;
class LLMenuButton
: public LLButton
{
+ LOG_CLASS(LLMenuButton);
+
public:
typedef enum e_menu_position
{
@@ -53,7 +55,7 @@ public:
{
// filename for it's toggleable menu
Optional<std::string> menu_filename;
- Optional<EMenuPosition> position;
+ Optional<EMenuPosition, MenuPositions> position;
Params();
};
@@ -68,13 +70,15 @@ public:
void hideMenu();
LLToggleableMenu* getMenu();
- void setMenu(LLToggleableMenu* menu, EMenuPosition position = MP_TOP_LEFT);
+ void setMenu(const std::string& menu_filename, EMenuPosition position = MP_TOP_LEFT);
+ void setMenu(LLToggleableMenu* menu, EMenuPosition position = MP_TOP_LEFT, bool take_ownership = false);
void setMenuPosition(EMenuPosition position) { mMenuPosition = position; }
protected:
friend class LLUICtrlFactory;
LLMenuButton(const Params&);
+ ~LLMenuButton();
void toggleMenu();
void updateMenuOrigin();
@@ -82,11 +86,14 @@ protected:
void onMenuVisibilityChange(const LLSD& param);
private:
+ void cleanup();
+
LLHandle<LLView> mMenuHandle;
bool mIsMenuShown;
EMenuPosition mMenuPosition;
S32 mX;
S32 mY;
+ bool mOwnMenu; // true if we manage the menu lifetime
};
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index ff6928ffda..32e5cdd556 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -4021,11 +4021,6 @@ BOOL LLContextMenu::handleRightMouseUp( S32 x, S32 y, MASK mask )
return result;
}
-void LLContextMenu::draw()
-{
- LLMenuGL::draw();
-}
-
BOOL LLContextMenu::appendContextSubMenu(LLContextMenu *menu)
{
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 36f3ba34b9..c6ee5434b0 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -668,8 +668,6 @@ public:
// can't set visibility directly, must call show or hide
virtual void setVisible (BOOL visible);
- virtual void draw ();
-
virtual void show (S32 x, S32 y);
virtual void hide ();
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 8aa548b974..9ef9b4bbec 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -246,7 +246,7 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica
LLParamSDParser parser;
parser.writeSD(mFormData, p.form_elements);
- if (!mFormData.isArray())
+ if (!mFormData.isArray() && !mFormData.isUndefined())
{
// change existing contents to a one element array
LLSD new_llsd_array = LLSD::emptyArray();
@@ -407,9 +407,12 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par
mURLOption(p.url.option),
mURLTarget(p.url.target),
mUnique(p.unique.isProvided()),
+ mCombineBehavior(p.unique.combine),
mPriority(p.priority),
mPersist(p.persist),
- mDefaultFunctor(p.functor.isProvided() ? p.functor() : p.name())
+ mDefaultFunctor(p.functor.isProvided() ? p.functor() : p.name()),
+ mLogToChat(p.log_to_chat),
+ mLogToIM(p.log_to_im)
{
if (p.sound.isProvided()
&& LLUI::sSettingGroups["config"]->controlExists(p.sound))
@@ -886,6 +889,28 @@ std::string LLNotification::getURL() const
return (mTemplatep ? url : "");
}
+bool LLNotification::canLogToChat() const
+{
+ return mTemplatep->mLogToChat;
+}
+
+bool LLNotification::canLogToIM() const
+{
+ return mTemplatep->mLogToIM;
+}
+
+bool LLNotification::hasFormElements() const
+{
+ return mTemplatep->mForm->getNumElements() != 0;
+}
+
+LLNotification::ECombineBehavior LLNotification::getCombineBehavior() const
+{
+ return mTemplatep->mCombineBehavior;
+}
+
+
+
// =========================================================
// LLNotificationChannel implementation
// ---
@@ -946,7 +971,7 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
std::string cmd = payload["sigtype"];
LLNotificationSet::iterator foundItem = mItems.find(pNotification);
bool wasFound = (foundItem != mItems.end());
- bool passesFilter = mFilter(pNotification);
+ bool passesFilter = mFilter ? mFilter(pNotification) : true;
// first, we offer the result of the filter test to the simple
// signals for pass/fail. One of these is guaranteed to be called.
@@ -1051,41 +1076,28 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
return abortProcessing;
}
-/* static */
-LLNotificationChannelPtr LLNotificationChannel::buildChannel(const std::string& name,
- const std::string& parent,
- LLNotificationFilter filter,
- LLNotificationComparator comparator)
+LLNotificationChannel::LLNotificationChannel(const Params& p)
+: LLNotificationChannelBase(p.filter(), p.comparator()),
+ LLInstanceTracker<LLNotificationChannel, std::string>(p.name.isProvided() ? p.name : LLUUID::generateNewID().asString()),
+ mName(p.name.isProvided() ? p.name : LLUUID::generateNewID().asString())
{
- // note: this is not a leak; notifications are self-registering.
- // This factory helps to prevent excess deletions by making sure all smart
- // pointers to notification channels come from the same source
- new LLNotificationChannel(name, parent, filter, comparator);
- return LLNotifications::instance().getChannel(name);
+ BOOST_FOREACH(const std::string& source, p.sources)
+{
+ connectToChannel(source);
+ }
}
LLNotificationChannel::LLNotificationChannel(const std::string& name,
const std::string& parent,
LLNotificationFilter filter,
- LLNotificationComparator comparator) :
-LLNotificationChannelBase(filter, comparator),
-mName(name),
-mParent(parent)
+ LLNotificationComparator comparator)
+: LLNotificationChannelBase(filter, comparator),
+ LLInstanceTracker<LLNotificationChannel, std::string>(name),
+ mName(name)
{
- // store myself in the channel map
- LLNotifications::instance().addChannel(LLNotificationChannelPtr(this));
// bind to notification broadcast
- if (parent.empty())
- {
- LLNotifications::instance().connectChanged(
- boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
- }
- else
- {
- LLNotificationChannelPtr p = LLNotifications::instance().getChannel(parent);
- p->connectChanged(boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
- }
+ connectToChannel(parent);
}
@@ -1128,6 +1140,21 @@ std::string LLNotificationChannel::summarize()
return s;
}
+void LLNotificationChannel::connectToChannel( const std::string& channel_name )
+{
+ if (channel_name.empty())
+ {
+ LLNotifications::instance().connectChanged(
+ boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
+ }
+ else
+ {
+ LLNotificationChannelPtr p = LLNotifications::instance().getChannel(channel_name);
+ p->connectChanged(boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
+ }
+}
+
+
// ---
// END OF LLNotificationChannel implementation
@@ -1220,6 +1247,8 @@ bool LLNotifications::failedUniquenessTest(const LLSD& payload)
return false;
}
+ if (pNotif->getCombineBehavior() == LLNotification::USE_NEWEST)
+ {
// Update the existing unique notification with the data from this particular instance...
// This guarantees that duplicate notifications will be collapsed to the one
// most recently triggered
@@ -1238,25 +1267,14 @@ bool LLNotifications::failedUniquenessTest(const LLSD& payload)
cancel(pNotif);
}
}
+ }
return false;
}
-
-void LLNotifications::addChannel(LLNotificationChannelPtr pChan)
-{
- mChannels[pChan->getName()] = pChan;
-}
-
LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelName)
{
- ChannelMap::iterator p = mChannels.find(channelName);
- if(p == mChannels.end())
- {
- llerrs << "Did not find channel named " << channelName << llendl;
- return LLNotificationChannelPtr();
- }
- return p->second;
+ return LLNotificationChannelPtr(LLNotificationChannel::getInstance(channelName));
}
@@ -1272,24 +1290,21 @@ void LLNotifications::createDefaultChannels()
{
// now construct the various channels AFTER loading the notifications,
// because the history channel is going to rewrite the stored notifications file
- LLNotificationChannel::buildChannel("Enabled", "",
- !boost::bind(&LLNotifications::getIgnoreAllNotifications, this));
- LLNotificationChannel::buildChannel("Expiration", "Enabled",
- boost::bind(&LLNotifications::expirationFilter, this, _1));
- LLNotificationChannel::buildChannel("Unexpired", "Enabled",
- !boost::bind(&LLNotifications::expirationFilter, this, _1)); // use negated bind
- LLNotificationChannel::buildChannel("Unique", "Unexpired",
- boost::bind(&LLNotifications::uniqueFilter, this, _1));
- LLNotificationChannel::buildChannel("Ignore", "Unique",
- filterIgnoredNotifications);
- LLNotificationChannel::buildChannel("VisibilityRules", "Ignore",
- boost::bind(&LLNotifications::isVisibleByRules, this, _1));
- LLNotificationChannel::buildChannel("Visible", "VisibilityRules",
- &LLNotificationFilters::includeEverything);
-
- // create special persistent notification channel
- // this isn't a leak, don't worry about the empty "new"
- new LLPersistentNotificationChannel();
+ mDefaultChannels.push_back(new LLNotificationChannel("Enabled", "",
+ !boost::bind(&LLNotifications::getIgnoreAllNotifications, this)));
+ mDefaultChannels.push_back(new LLNotificationChannel("Expiration", "Enabled",
+ boost::bind(&LLNotifications::expirationFilter, this, _1)));
+ mDefaultChannels.push_back(new LLNotificationChannel("Unexpired", "Enabled",
+ !boost::bind(&LLNotifications::expirationFilter, this, _1))); // use negated bind
+ mDefaultChannels.push_back(new LLNotificationChannel("Unique", "Unexpired",
+ boost::bind(&LLNotifications::uniqueFilter, this, _1)));
+ mDefaultChannels.push_back(new LLNotificationChannel("Ignore", "Unique",
+ filterIgnoredNotifications));
+ mDefaultChannels.push_back(new LLNotificationChannel("VisibilityRules", "Ignore",
+ boost::bind(&LLNotifications::isVisibleByRules, this, _1)));
+ mDefaultChannels.push_back(new LLNotificationChannel("Visible", "VisibilityRules",
+ &LLNotificationFilters::includeEverything));
+ mDefaultChannels.push_back(new LLPersistentNotificationChannel());
// connect action methods to these channels
LLNotifications::instance().getChannel("Enabled")->
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 3df2efcac3..21a4318aab 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -94,10 +94,11 @@
// and we need this to manage the notification callbacks
#include "llevents.h"
#include "llfunctorregistry.h"
-#include "llpointer.h"
#include "llinitparam.h"
#include "llnotificationslistener.h"
#include "llnotificationptr.h"
+#include "llpointer.h"
+#include "llrefcount.h"
class LLAvatarName;
typedef enum e_notification_priority
@@ -296,6 +297,7 @@ LOG_CLASS(LLNotification);
friend class LLNotifications;
public:
+
// parameter object used to instantiate a new notification
struct Params : public LLInitParam::Block<Params>
{
@@ -513,7 +515,17 @@ public:
std::string getURL() const;
S32 getURLOption() const;
S32 getURLOpenExternally() const;
+ bool canLogToChat() const;
+ bool canLogToIM() const;
+ bool hasFormElements() const;
+
+ typedef enum e_combine_behavior
+ {
+ USE_NEWEST,
+ USE_OLDEST
+ } ECombineBehavior;
+ ECombineBehavior getCombineBehavior() const;
const LLNotificationFormPtr getForm();
const LLDate getExpiration() const
@@ -704,7 +716,8 @@ typedef std::multimap<std::string, LLNotificationPtr> LLNotificationMap;
// all of the built-in tests should attach to the "Visible" channel
//
class LLNotificationChannelBase :
- public LLEventTrackable
+ public LLEventTrackable,
+ public LLRefCount
{
LOG_CLASS(LLNotificationChannelBase);
public:
@@ -784,32 +797,47 @@ protected:
// destroy it, but if it becomes necessary to do so, the shared_ptr model
// will ensure that we don't leak resources.
class LLNotificationChannel;
-typedef boost::shared_ptr<LLNotificationChannel> LLNotificationChannelPtr;
+typedef boost::intrusive_ptr<LLNotificationChannel> LLNotificationChannelPtr;
// manages a list of notifications
// Note that if this is ever copied around, we might find ourselves with multiple copies
// of a queue with notifications being added to different nonequivalent copies. So we
-// make it inherit from boost::noncopyable, and then create a map of shared_ptr to manage it.
-//
-// NOTE: LLNotificationChannel is self-registering. The *correct* way to create one is to
-// do something like:
-// LLNotificationChannel::buildChannel("name", "parent"...);
-// This returns an LLNotificationChannelPtr, which you can store, or
-// you can then retrieve the channel by using the registry:
-// LLNotifications::instance().getChannel("name")...
+// make it inherit from boost::noncopyable, and then create a map of LLPointer to manage it.
//
class LLNotificationChannel :
boost::noncopyable,
- public LLNotificationChannelBase
+ public LLNotificationChannelBase,
+ public LLInstanceTracker<LLNotificationChannel, std::string>
{
LOG_CLASS(LLNotificationChannel);
public:
+ // Notification Channels have a filter, which determines which notifications
+ // will be added to this channel.
+ // Channel filters cannot change.
+ struct Params : public LLInitParam::Block<Params>
+ {
+ Mandatory<std::string> name;
+ Optional<LLNotificationFilter> filter;
+ Optional<LLNotificationComparator> comparator;
+ Multiple<std::string> sources;
+
+ Params()
+ : comparator("", LLNotificationComparators::orderByUUID())
+ {}
+ };
+
+ LLNotificationChannel(const Params& p = Params());
+
+ LLNotificationChannel(const std::string& name, const std::string& parent,
+ LLNotificationFilter filter, LLNotificationComparator comparator=LLNotificationComparators::orderByUUID());
+
virtual ~LLNotificationChannel() {}
typedef LLNotificationSet::iterator Iterator;
std::string getName() const { return mName; }
- std::string getParentChannelName() { return mParent; }
+
+ void connectToChannel(const std::string& channel_name);
bool isEmpty() const;
@@ -822,21 +850,6 @@ public:
std::string summarize();
- // factory method for constructing these channels; since they're self-registering,
- // we want to make sure that you can't use new to make them
- static LLNotificationChannelPtr buildChannel(const std::string& name, const std::string& parent,
- LLNotificationFilter filter=LLNotificationFilters::includeEverything,
- LLNotificationComparator comparator=LLNotificationComparators::orderByUUID());
-
-protected:
- // Notification Channels have a filter, which determines which notifications
- // will be added to this channel.
- // Channel filters cannot change.
- // Channels have a protected constructor so you can't make smart pointers that don't
- // come from our internal reference; call NotificationChannel::build(args)
- LLNotificationChannel(const std::string& name, const std::string& parent,
- LLNotificationFilter filter, LLNotificationComparator comparator);
-
private:
std::string mName;
std::string mParent;
@@ -923,10 +936,6 @@ public:
void createDefaultChannels();
- typedef std::map<std::string, LLNotificationChannelPtr> ChannelMap;
- ChannelMap mChannels;
-
- void addChannel(LLNotificationChannelPtr pChan);
LLNotificationChannelPtr getChannel(const std::string& channelName);
std::string getGlobalString(const std::string& key) const;
@@ -965,6 +974,7 @@ private:
bool mIgnoreAllNotifications;
boost::scoped_ptr<LLNotificationsListener> mListener;
+ std::vector<LLNotificationChannelPtr> mDefaultChannels;
};
/**
diff --git a/indra/llui/llnotificationslistener.cpp b/indra/llui/llnotificationslistener.cpp
index 3bbeb3a778..e4e127336b 100644
--- a/indra/llui/llnotificationslistener.cpp
+++ b/indra/llui/llnotificationslistener.cpp
@@ -121,13 +121,13 @@ void LLNotificationsListener::listChannels(const LLSD& params) const
{
LLReqID reqID(params);
LLSD response(reqID.makeResponse());
- for (LLNotifications::ChannelMap::const_iterator cmi(mNotifications.mChannels.begin()),
- cmend(mNotifications.mChannels.end());
+ for (LLNotificationChannel::instance_iter cmi(LLNotificationChannel::beginInstances()),
+ cmend(LLNotificationChannel::endInstances());
cmi != cmend; ++cmi)
{
LLSD channelInfo;
- channelInfo["parent"] = cmi->second->getParentChannelName();
- response[cmi->first] = channelInfo;
+ //channelInfo["parent"] = cmi->second->getParentChannelName();
+ response[cmi->getName()] = channelInfo;
}
LLEventPumps::instance().obtain(params["reply"]).post(response);
}
diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h
index fb50c9c123..f7d08ae1f4 100644
--- a/indra/llui/llnotificationtemplate.h
+++ b/indra/llui/llnotificationtemplate.h
@@ -61,6 +61,17 @@ typedef boost::shared_ptr<LLNotificationForm> LLNotificationFormPtr;
// from the appropriate local language directory).
struct LLNotificationTemplate
{
+ struct CombineBehaviorNames
+ : public LLInitParam::TypeValuesHelper<LLNotification::ECombineBehavior, CombineBehaviorNames>
+ {
+ static void declareValues()
+ {
+ declare("newest", LLNotification::USE_NEWEST);
+ declare("oldest", LLNotification::USE_OLDEST);
+ }
+ };
+
+
struct GlobalString : public LLInitParam::Block<GlobalString>
{
Mandatory<std::string> name,
@@ -94,9 +105,11 @@ struct LLNotificationTemplate
Optional<LLInitParam::Flag> dummy_val;
public:
Multiple<UniquenessContext> contexts;
+ Optional<LLNotification::ECombineBehavior, CombineBehaviorNames> combine;
UniquenessConstraint()
: contexts("context"),
+ combine("combine", LLNotification::USE_NEWEST),
dummy_val("")
{}
};
@@ -170,7 +183,9 @@ struct LLNotificationTemplate
struct Params : public LLInitParam::Block<Params>
{
Mandatory<std::string> name;
- Optional<bool> persist;
+ Optional<bool> persist,
+ log_to_im,
+ log_to_chat;
Optional<std::string> functor,
icon,
label,
@@ -190,6 +205,8 @@ struct LLNotificationTemplate
Params()
: name("name"),
persist("persist", false),
+ log_to_im("log_to_im", false),
+ log_to_chat("log_to_chat", true),
functor("functor"),
icon("icon"),
label("label"),
@@ -245,6 +262,7 @@ struct LLNotificationTemplate
// (used for things like progress indications, or repeating warnings
// like "the grid is going down in N minutes")
bool mUnique;
+ LLNotification::ECombineBehavior mCombineBehavior;
// if we want to be unique only if a certain part of the payload or substitutions args
// are constant specify the field names for the payload. The notification will only be
// combined if all of the fields named in the context are identical in the
@@ -291,6 +309,10 @@ struct LLNotificationTemplate
LLUUID mSoundEffect;
// List of tags that rules can match against.
std::list<std::string> mTags;
+
+ // inject these notifications into chat/IM streams
+ bool mLogToChat;
+ bool mLogToIM;
};
#endif //LL_LLNOTIFICATION_TEMPLATE_H
diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp
index 0e29873bb0..bcfb38aa11 100644
--- a/indra/llui/llsdparam.cpp
+++ b/indra/llui/llsdparam.cpp
@@ -313,7 +313,7 @@ namespace LLInitParam
{
// LLSD specialization
// block param interface
- bool ParamValue<LLSD, TypeValues<LLSD>, false>::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name)
+ bool ParamValue<LLSD, NOT_BLOCK>::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name)
{
LLSD& sd = LLParamSDParserUtilities::getSDWriteNode(mValue, name_stack);
@@ -328,12 +328,12 @@ namespace LLInitParam
}
//static
- void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack)
+ void ParamValue<LLSD, NOT_BLOCK>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack)
{
p.writeValue<LLSD::String>(sd.asString(), name_stack);
}
- void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const
+ void ParamValue<LLSD, NOT_BLOCK>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const
{
// read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc)
Parser::name_stack_t stack;
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index b5e27616b7..8da0d58f51 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -974,31 +974,31 @@ void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha)
{
if (!LLGLSLShader::sNoFixedFunction)
{
- // Initialize the first time this is called.
- const S32 PIXELS = 32;
- static GLubyte checkerboard[PIXELS * PIXELS];
- static BOOL first = TRUE;
- if( first )
+ // Initialize the first time this is called.
+ const S32 PIXELS = 32;
+ static GLubyte checkerboard[PIXELS * PIXELS];
+ static BOOL first = TRUE;
+ if( first )
+ {
+ for( S32 i = 0; i < PIXELS; i++ )
{
- for( S32 i = 0; i < PIXELS; i++ )
+ for( S32 j = 0; j < PIXELS; j++ )
{
- for( S32 j = 0; j < PIXELS; j++ )
- {
- checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF;
- }
+ checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF;
}
- first = FALSE;
}
+ first = FALSE;
+ }
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- // ...white squares
- gGL.color4f( 1.f, 1.f, 1.f, alpha );
- gl_rect_2d(rect);
+ // ...white squares
+ gGL.color4f( 1.f, 1.f, 1.f, alpha );
+ gl_rect_2d(rect);
- // ...gray squares
- gGL.color4f( .7f, .7f, .7f, alpha );
- gGL.flush();
+ // ...gray squares
+ gGL.color4f( .7f, .7f, .7f, alpha );
+ gGL.flush();
glPolygonStipple( checkerboard );
@@ -1474,144 +1474,132 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,
gGL.popUIMatrix();
}
-void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width,
- const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec,
- const U32 edges)
+void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect,
+ const LLVector3& width_vec, const LLVector3& height_vec)
{
- LLVector3 left_border_width = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? border_width : LLVector3::zero;
- LLVector3 right_border_width = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? border_width : LLVector3::zero;
-
- LLVector3 top_border_height = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? border_height : LLVector3::zero;
- LLVector3 bottom_border_height = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? border_height : LLVector3::zero;
-
-
gGL.begin(LLRender::QUADS);
{
// draw bottom left
- gGL.texCoord2f(0.f, 0.f);
+ gGL.texCoord2f(clip_rect.mLeft, clip_rect.mBottom);
gGL.vertex3f(0.f, 0.f, 0.f);
- gGL.texCoord2f(border_scale.mV[VX], 0.f);
- gGL.vertex3fv(left_border_width.mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
- gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
- gGL.vertex3fv((left_border_width + bottom_border_height).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
- gGL.texCoord2f(0.f, border_scale.mV[VY]);
- gGL.vertex3fv(bottom_border_height.mV);
+ gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
// draw bottom middle
- gGL.texCoord2f(border_scale.mV[VX], 0.f);
- gGL.vertex3fv(left_border_width.mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
- gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f);
- gGL.vertex3fv((width_vec - right_border_width).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
- gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
- gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
- gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
- gGL.vertex3fv((left_border_width + bottom_border_height).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
// draw bottom right
- gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f);
- gGL.vertex3fv((width_vec - right_border_width).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
- gGL.texCoord2f(1.f, 0.f);
+ gGL.texCoord2f(clip_rect.mRight, clip_rect.mBottom);
gGL.vertex3fv(width_vec.mV);
- gGL.texCoord2f(1.f, border_scale.mV[VY]);
- gGL.vertex3fv((width_vec + bottom_border_height).mV);
+ gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
- gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
- gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
// draw left
- gGL.texCoord2f(0.f, border_scale.mV[VY]);
- gGL.vertex3fv(bottom_border_height.mV);
+ gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
- gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
- gGL.vertex3fv((left_border_width + bottom_border_height).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
- gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
- gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((height_vec - top_border_height).mV);
+ gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
// draw middle
- gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
- gGL.vertex3fv((left_border_width + bottom_border_height).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
- gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
- gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
- gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
- gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
// draw right
- gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
- gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
- gGL.texCoord2f(1.f, border_scale.mV[VY]);
- gGL.vertex3fv((width_vec + bottom_border_height).mV);
+ gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
- gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((width_vec + height_vec - top_border_height).mV);
+ gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
- gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
// draw top left
- gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((height_vec - top_border_height).mV);
+ gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
- gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
- gGL.texCoord2f(border_scale.mV[VX], 1.f);
- gGL.vertex3fv((left_border_width + height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
- gGL.texCoord2f(0.f, 1.f);
+ gGL.texCoord2f(clip_rect.mLeft, clip_rect.mTop);
gGL.vertex3fv((height_vec).mV);
// draw top middle
- gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
- gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
- gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f);
- gGL.vertex3fv((width_vec - right_border_width + height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
- gGL.texCoord2f(border_scale.mV[VX], 1.f);
- gGL.vertex3fv((left_border_width + height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
// draw top right
- gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
- gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]);
- gGL.vertex3fv((width_vec + height_vec - top_border_height).mV);
+ gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
- gGL.texCoord2f(1.f, 1.f);
+ gGL.texCoord2f(clip_rect.mRight, clip_rect.mTop);
gGL.vertex3fv((width_vec + height_vec).mV);
- gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f);
- gGL.vertex3fv((width_vec - right_border_width + height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
}
gGL.end();
}
-void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec)
-{
- gl_segmented_rect_3d_tex(border_scale, border_width, border_height, width_vec, height_vec, ROUNDED_RECT_TOP);
-}
void LLUI::initClass(const settings_map_t& settings,
LLImageProviderInterface* image_provider,
@@ -2114,7 +2102,7 @@ const LLView* LLUI::resolvePath(const LLView* context, const std::string& path)
namespace LLInitParam
{
- ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color)
+ ParamValue<LLUIColor>::ParamValue(const LLUIColor& color)
: super_t(color),
red("red"),
green("green"),
@@ -2125,7 +2113,7 @@ namespace LLInitParam
updateBlockFromValue(false);
}
- void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()
+ void ParamValue<LLUIColor>::updateValueFromBlock()
{
if (control.isProvided() && !control().empty())
{
@@ -2137,7 +2125,7 @@ namespace LLInitParam
}
}
- void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue(bool make_block_authoritative)
+ void ParamValue<LLUIColor>::updateBlockFromValue(bool make_block_authoritative)
{
LLColor4 color = getValue();
red.set(color.mV[VRED], make_block_authoritative);
@@ -2153,7 +2141,7 @@ namespace LLInitParam
&& !(b->getFontDesc() < a->getFontDesc());
}
- ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp)
+ ParamValue<const LLFontGL*>::ParamValue(const LLFontGL* fontp)
: super_t(fontp),
name("name"),
size("size"),
@@ -2167,7 +2155,7 @@ namespace LLInitParam
updateBlockFromValue(false);
}
- void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
+ void ParamValue<const LLFontGL*>::updateValueFromBlock()
{
const LLFontGL* res_fontp = LLFontGL::getFontByName(name);
if (res_fontp)
@@ -2190,7 +2178,7 @@ namespace LLInitParam
}
}
- void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue(bool make_block_authoritative)
+ void ParamValue<const LLFontGL*>::updateBlockFromValue(bool make_block_authoritative)
{
if (getValue())
{
@@ -2200,7 +2188,7 @@ namespace LLInitParam
}
}
- ParamValue<LLRect, TypeValues<LLRect> >::ParamValue(const LLRect& rect)
+ ParamValue<LLRect>::ParamValue(const LLRect& rect)
: super_t(rect),
left("left"),
top("top"),
@@ -2212,7 +2200,7 @@ namespace LLInitParam
updateBlockFromValue(false);
}
- void ParamValue<LLRect, TypeValues<LLRect> >::updateValueFromBlock()
+ void ParamValue<LLRect>::updateValueFromBlock()
{
LLRect rect;
@@ -2276,7 +2264,7 @@ namespace LLInitParam
updateValue(rect);
}
- void ParamValue<LLRect, TypeValues<LLRect> >::updateBlockFromValue(bool make_block_authoritative)
+ void ParamValue<LLRect>::updateBlockFromValue(bool make_block_authoritative)
{
// because of the ambiguity in specifying a rect by position and/or dimensions
// we use the lowest priority pairing so that any valid pairing in xui
@@ -2293,7 +2281,7 @@ namespace LLInitParam
height.set(value.getHeight(), make_block_authoritative);
}
- ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::ParamValue(const LLCoordGL& coord)
+ ParamValue<LLCoordGL>::ParamValue(const LLCoordGL& coord)
: super_t(coord),
x("x"),
y("y")
@@ -2301,12 +2289,12 @@ namespace LLInitParam
updateBlockFromValue(false);
}
- void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateValueFromBlock()
+ void ParamValue<LLCoordGL>::updateValueFromBlock()
{
updateValue(LLCoordGL(x, y));
}
- void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateBlockFromValue(bool make_block_authoritative)
+ void ParamValue<LLCoordGL>::updateBlockFromValue(bool make_block_authoritative)
{
x.set(getValue().mX, make_block_authoritative);
y.set(getValue().mY, make_block_authoritative);
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 28e84fa444..1fbfbd7a07 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -127,8 +127,7 @@ typedef enum e_rounded_edge
void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL);
void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);
-void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec, U32 edges = ROUNDED_RECT_ALL);
-void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec);
+void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect, const LLVector3& width_vec, const LLVector3& height_vec);
inline void gl_rect_2d( const LLRect& rect, BOOL filled )
{
@@ -512,7 +511,7 @@ public:
namespace LLInitParam
{
template<>
- class ParamValue<LLRect, TypeValues<LLRect> >
+ class ParamValue<LLRect>
: public CustomParamValue<LLRect>
{
typedef CustomParamValue<LLRect> super_t;
@@ -531,7 +530,7 @@ namespace LLInitParam
};
template<>
- class ParamValue<LLUIColor, TypeValues<LLUIColor> >
+ class ParamValue<LLUIColor>
: public CustomParamValue<LLUIColor>
{
typedef CustomParamValue<LLUIColor> super_t;
@@ -549,7 +548,7 @@ namespace LLInitParam
};
template<>
- class ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >
+ class ParamValue<const LLFontGL*>
: public CustomParamValue<const LLFontGL* >
{
typedef CustomParamValue<const LLFontGL*> super_t;
@@ -589,7 +588,7 @@ namespace LLInitParam
template<>
- class ParamValue<LLCoordGL, TypeValues<LLCoordGL> >
+ class ParamValue<LLCoordGL>
: public CustomParamValue<LLCoordGL>
{
typedef CustomParamValue<LLCoordGL> super_t;
diff --git a/indra/llui/lluiimage.cpp b/indra/llui/lluiimage.cpp
index 1d9ce29ba9..9ed98f941f 100644
--- a/indra/llui/lluiimage.cpp
+++ b/indra/llui/lluiimage.cpp
@@ -112,6 +112,50 @@ void LLUIImage::drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4&
drawSolid(border_rect, color);
}
+void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis,
+ const LLRect& rect, const LLColor4& color)
+{
+ F32 border_scale = 1.f;
+ F32 border_height = (1.f - mScaleRegion.getHeight()) * getHeight();
+ F32 border_width = (1.f - mScaleRegion.getWidth()) * getWidth();
+ if (rect.getHeight() < border_height || rect.getWidth() < border_width)
+ {
+ if(border_height - rect.getHeight() > border_width - rect.getWidth())
+ {
+ border_scale = (F32)rect.getHeight() / border_height;
+ }
+ else
+ {
+ border_scale = (F32)rect.getWidth() / border_width;
+ }
+ }
+
+ LLUI::pushMatrix();
+ {
+ LLVector3 rect_origin = origin_agent + (rect.mLeft * x_axis) + (rect.mBottom * y_axis);
+ LLUI::translate(rect_origin.mV[VX],
+ rect_origin.mV[VY],
+ rect_origin.mV[VZ]);
+ gGL.getTexUnit(0)->bind(getImage());
+ gGL.color4fv(color.mV);
+
+ LLRectf center_uv_rect(mClipRegion.mLeft + mScaleRegion.mLeft * mClipRegion.getWidth(),
+ mClipRegion.mBottom + mScaleRegion.mTop * mClipRegion.getHeight(),
+ mClipRegion.mLeft + mScaleRegion.mRight * mClipRegion.getWidth(),
+ mClipRegion.mBottom + mScaleRegion.mBottom * mClipRegion.getHeight());
+ gl_segmented_rect_3d_tex(mClipRegion,
+ center_uv_rect,
+ LLRectf(border_width * border_scale * 0.5f / (F32)rect.getWidth(),
+ (rect.getHeight() - (border_height * border_scale * 0.5f)) / (F32)rect.getHeight(),
+ (rect.getWidth() - (border_width * border_scale * 0.5f)) / (F32)rect.getWidth(),
+ (border_height * border_scale * 0.5f) / (F32)rect.getHeight()),
+ rect.getWidth() * x_axis,
+ rect.getHeight() * y_axis);
+
+ } LLUI::popMatrix();
+}
+
+
S32 LLUIImage::getWidth() const
{
// return clipped dimensions of actual image area
@@ -155,7 +199,7 @@ void LLUIImage::onImageLoaded()
namespace LLInitParam
{
- void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
+ void ParamValue<LLUIImage*>::updateValueFromBlock()
{
// The keyword "none" is specifically requesting a null image
// do not default to current value. Used to overwrite template images.
@@ -172,7 +216,7 @@ namespace LLInitParam
}
}
- void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue(bool make_block_authoritative)
+ void ParamValue<LLUIImage*>::updateBlockFromValue(bool make_block_authoritative)
{
if (getValue() == NULL)
{
diff --git a/indra/llui/lluiimage.h b/indra/llui/lluiimage.h
index f07e8fa746..7817ba1c7b 100644
--- a/indra/llui/lluiimage.h
+++ b/indra/llui/lluiimage.h
@@ -64,7 +64,9 @@ public:
void drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const;
void drawBorder(const LLRect& rect, const LLColor4& color, S32 border_width) const { drawBorder(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color, border_width); }
void drawBorder(S32 x, S32 y, const LLColor4& color, S32 border_width) const { drawBorder(x, y, getWidth(), getHeight(), color, border_width); }
-
+
+ void draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis, const LLRect& rect, const LLColor4& color);
+
const std::string& getName() const { return mName; }
virtual S32 getWidth() const;
@@ -92,7 +94,7 @@ protected:
namespace LLInitParam
{
template<>
- class ParamValue<LLUIImage*, TypeValues<LLUIImage*> >
+ class ParamValue<LLUIImage*>
: public CustomParamValue<LLUIImage*>
{
typedef boost::add_reference<boost::add_const<LLUIImage*>::type>::type T_const_ref;
@@ -100,7 +102,7 @@ namespace LLInitParam
public:
Optional<std::string> name;
- ParamValue(LLUIImage* const& image)
+ ParamValue(LLUIImage* const& image = NULL)
: super_t(image)
{
updateBlockFromValue(false);
diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp
index c75df86891..9cb6a89eee 100644
--- a/indra/llui/tests/llurlentry_stub.cpp
+++ b/indra/llui/tests/llurlentry_stub.cpp
@@ -113,7 +113,7 @@ namespace LLInitParam
mEnclosingBlockOffset = (U16)(my_addr - block_addr);
}
- void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name){}
+ void BlockDescriptor::addParam(const ParamDescriptorPtr in_param, const char* char_name){}
void BaseBlock::addSynonym(Param& param, const std::string& synonym) {}
param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;}
@@ -127,14 +127,14 @@ namespace LLInitParam
bool BaseBlock::mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }
bool BaseBlock::validateBlock(bool emit_errors) const { return true; }
- ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color)
+ ParamValue<LLUIColor>::ParamValue(const LLUIColor& color)
: super_t(color)
{}
- void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()
+ void ParamValue<LLUIColor>::updateValueFromBlock()
{}
- void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue(bool)
+ void ParamValue<LLUIColor>::updateBlockFromValue(bool)
{}
bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)
@@ -142,14 +142,14 @@ namespace LLInitParam
return false;
}
- ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp)
+ ParamValue<const LLFontGL*>::ParamValue(const LLFontGL* fontp)
: super_t(fontp)
{}
- void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
+ void ParamValue<const LLFontGL*>::updateValueFromBlock()
{}
- void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue(bool)
+ void ParamValue<const LLFontGL*>::updateBlockFromValue(bool)
{}
void TypeValues<LLFontGL::HAlign>::declareValues()
@@ -161,10 +161,10 @@ namespace LLInitParam
void TypeValues<LLFontGL::ShadowType>::declareValues()
{}
- void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
+ void ParamValue<LLUIImage*>::updateValueFromBlock()
{}
- void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue(bool)
+ void ParamValue<LLUIImage*>::updateBlockFromValue(bool)
{}
diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp
index 7183413463..36402f5b27 100644
--- a/indra/llui/tests/llurlmatch_test.cpp
+++ b/indra/llui/tests/llurlmatch_test.cpp
@@ -74,7 +74,7 @@ namespace LLInitParam
S32 max_count){}
ParamDescriptor::~ParamDescriptor() {}
- void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name){}
+ void BlockDescriptor::addParam(const ParamDescriptorPtr in_param, const char* char_name){}
param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;}
void BaseBlock::addSynonym(Param& param, const std::string& synonym) {}
@@ -97,14 +97,14 @@ namespace LLInitParam
bool BaseBlock::mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }
bool BaseBlock::validateBlock(bool emit_errors) const { return true; }
- ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color)
+ ParamValue<LLUIColor>::ParamValue(const LLUIColor& color)
: super_t(color)
{}
- void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()
+ void ParamValue<LLUIColor>::updateValueFromBlock()
{}
- void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue(bool)
+ void ParamValue<LLUIColor>::updateBlockFromValue(bool)
{}
bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)
@@ -113,14 +113,14 @@ namespace LLInitParam
}
- ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp)
+ ParamValue<const LLFontGL*>::ParamValue(const LLFontGL* fontp)
: super_t(fontp)
{}
- void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
+ void ParamValue<const LLFontGL*>::updateValueFromBlock()
{}
- void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue(bool)
+ void ParamValue<const LLFontGL*>::updateBlockFromValue(bool)
{}
void TypeValues<LLFontGL::HAlign>::declareValues()
@@ -132,10 +132,10 @@ namespace LLInitParam
void TypeValues<LLFontGL::ShadowType>::declareValues()
{}
- void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
+ void ParamValue<LLUIImage*>::updateValueFromBlock()
{}
- void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue(bool)
+ void ParamValue<LLUIImage*>::updateBlockFromValue(bool)
{}
bool ParamCompare<LLUIImage*, false>::equals(
diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp
index db72aa19b9..3cf145cdde 100644
--- a/indra/llxuixml/llinitparam.cpp
+++ b/indra/llxuixml/llinitparam.cpp
@@ -112,6 +112,35 @@ namespace LLInitParam
std::copy(src_block_data.mAllParams.begin(), src_block_data.mAllParams.end(), std::back_inserter(mAllParams));
}
+ void BlockDescriptor::addParam(const ParamDescriptorPtr in_param, const char* char_name)
+ {
+ // create a copy of the param descriptor in mAllParams
+ // so other data structures can store a pointer to it
+ mAllParams.push_back(in_param);
+ ParamDescriptorPtr param(mAllParams.back());
+
+ std::string name(char_name);
+ if ((size_t)param->mParamHandle > mMaxParamOffset)
+ {
+ llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
+ }
+
+ if (name.empty())
+ {
+ mUnnamedParams.push_back(param);
+ }
+ else
+ {
+ // don't use insert, since we want to overwrite existing entries
+ mNamedParams[name] = param;
+ }
+
+ if (param->mValidationFunc)
+ {
+ mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc));
+ }
+ }
+
BlockDescriptor::BlockDescriptor()
: mMaxParamOffset(0),
mInitializationState(UNINITIALIZED),
@@ -358,36 +387,6 @@ namespace LLInitParam
return false;
}
- //static
- void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name)
- {
- // create a copy of the param descriptor in mAllParams
- // so other data structures can store a pointer to it
- block_data.mAllParams.push_back(in_param);
- ParamDescriptorPtr param(block_data.mAllParams.back());
-
- std::string name(char_name);
- if ((size_t)param->mParamHandle > block_data.mMaxParamOffset)
- {
- llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
- }
-
- if (name.empty())
- {
- block_data.mUnnamedParams.push_back(param);
- }
- else
- {
- // don't use insert, since we want to overwrite existing entries
- block_data.mNamedParams[name] = param;
- }
-
- if (param->mValidationFunc)
- {
- block_data.mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc));
- }
- }
-
void BaseBlock::addSynonym(Param& param, const std::string& synonym)
{
BlockDescriptor& block_data = mostDerivedBlockDescriptor();
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 4ab1d891a3..2c854d8287 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -36,6 +36,71 @@
#include "llerror.h"
+namespace LLTypeTags
+{
+ template <typename INNER_TYPE, int _SORT_ORDER>
+ struct TypeTagBase
+ {
+ typedef void is_tag_t;
+ typedef INNER_TYPE inner_t;
+ static const int SORT_ORDER=_SORT_ORDER;
+ };
+
+ template <int VAL1, int VAL2>
+ struct GreaterThan
+ {
+ static const bool value = VAL1 > VAL2;
+ };
+
+ template<typename ITEM, typename REST, bool NEEDS_SWAP = GreaterThan<ITEM::SORT_ORDER, REST::SORT_ORDER>::value >
+ struct Swap
+ {
+ typedef typename ITEM::template Cons<REST>::value_t value_t;
+ };
+
+ template<typename ITEM, typename REST>
+ struct Swap<ITEM, REST, true>
+ {
+ typedef typename REST::template Cons<Swap<ITEM, typename REST::inner_t>::value_t>::value_t value_t;
+ };
+
+ template<typename T, typename SORTABLE = void>
+ struct IsSortable
+ {
+ static const bool value = false;
+ };
+
+ template<typename T>
+ struct IsSortable<T, typename T::is_tag_t>
+ {
+ static const bool value = true;
+ };
+
+ template<typename ITEM, typename REST, bool IS_REST_SORTABLE = IsSortable<REST>::value>
+ struct InsertInto
+ {
+ typedef typename ITEM::template Cons<REST>::value_t value_t;
+ };
+
+ template<typename ITEM, typename REST>
+ struct InsertInto <ITEM, REST, true>
+ {
+ typedef typename Swap<ITEM, REST>::value_t value_t;
+ };
+
+ template<typename T, bool SORTABLE = IsSortable<T>::value>
+ struct Sorted
+ {
+ typedef T value_t;
+ };
+
+ template<typename T>
+ struct Sorted <T, true>
+ {
+ typedef typename InsertInto<T, typename Sorted<typename T::inner_t>::value_t>::value_t value_t;
+ };
+}
+
namespace LLInitParam
{
// used to indicate no matching value to a given name when parsing
@@ -43,6 +108,8 @@ namespace LLInitParam
template<typename T> const T& defaultValue() { static T value; return value; }
+ // wraps comparison operator between any 2 values of the same type
+ // specialize to handle cases where equality isn't defined well, or at all
template <typename T, bool IS_BOOST_FUNCTION = boost::is_convertible<T, boost::function_base>::value >
struct ParamCompare
{
@@ -77,24 +144,123 @@ namespace LLInitParam
// helper functions and classes
typedef ptrdiff_t param_handle_t;
+ struct IS_A_BLOCK {};
+ struct NOT_BLOCK {};
+
+ // these templates allow us to distinguish between template parameters
+ // that derive from BaseBlock and those that don't
+ template<typename T, typename BLOCK_IDENTIFIER = void>
+ struct IsBlock
+ {
+ typedef NOT_BLOCK value_t;
+ };
+
+ template<typename T>
+ struct IsBlock<T, typename T::baseblock_base_class_t>
+ {
+ typedef IS_A_BLOCK value_t;
+ };
+
+ // ParamValue class directly manages the wrapped value
+ // by holding on to a copy (scalar params)
+ // or deriving from it (blocks)
+ // has specializations for custom value behavior
+ // and "tag" values like Lazy and Atomic
+ template<typename T, typename VALUE_IS_BLOCK = typename IsBlock<T>::value_t>
+ class ParamValue
+ {
+ typedef ParamValue<T, VALUE_IS_BLOCK> self_t;
+
+ public:
+ typedef T default_value_t;
+ typedef T value_t;
+
+ ParamValue(): mValue() {}
+ ParamValue(const default_value_t& other) : mValue(other) {}
+
+ void setValue(const value_t& val)
+ {
+ mValue = val;
+ }
+
+ const value_t& getValue() const
+ {
+ return mValue;
+ }
+
+ T& getValue()
+ {
+ return mValue;
+ }
+
+ protected:
+ T mValue;
+ };
+
+ template<typename T>
+ class ParamValue<T, IS_A_BLOCK>
+ : public T
+ {
+ typedef ParamValue<T, IS_A_BLOCK> self_t;
+ public:
+ typedef T default_value_t;
+ typedef T value_t;
+
+ ParamValue()
+ : T(),
+ mValidated(false)
+ {}
+
+ ParamValue(const default_value_t& other)
+ : T(other),
+ mValidated(false)
+ {}
+
+ void setValue(const value_t& val)
+ {
+ *this = val;
+ }
+
+ const value_t& getValue() const
+ {
+ return *this;
+ }
+
+ T& getValue()
+ {
+ return *this;
+ }
+
+ protected:
+ mutable bool mValidated; // lazy validation flag
+ };
+
// empty default implementation of key cache
// leverages empty base class optimization
template <typename T>
class TypeValues
+ : public ParamValue<typename LLTypeTags::Sorted<T>::value_t>
{
private:
struct Inaccessable{};
public:
typedef std::map<std::string, T> value_name_map_t;
typedef Inaccessable name_t;
+ typedef TypeValues<T> type_value_t;
+ typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t> param_value_t;
+ typedef typename param_value_t::value_t value_t;
+
+ TypeValues(const typename param_value_t::value_t& val)
+ : param_value_t(val)
+ {}
void setValueName(const std::string& key) {}
std::string getValueName() const { return ""; }
- std::string calcValueName(const T& value) const { return ""; }
+ std::string calcValueName(const value_t& value) const { return ""; }
void clearValueName() const {}
- static bool getValueFromName(const std::string& name, T& value)
+ static bool getValueFromName(const std::string& name, value_t& value)
{
return false;
}
@@ -109,15 +275,39 @@ namespace LLInitParam
return NULL;
}
+ void assignNamedValue(const Inaccessable& name)
+ {}
+
+ operator const value_t&() const
+ {
+ return param_value_t::getValue();
+ }
+
+ const value_t& operator()() const
+ {
+ return param_value_t::getValue();
+ }
+
static value_name_map_t* getValueNames() {return NULL;}
};
- template <typename T, typename DERIVED_TYPE = TypeValues<T> >
+ // helper class to implement name value lookups
+ // and caching of last used name
+ template <typename T, typename DERIVED_TYPE = TypeValues<T>, bool IS_SPECIALIZED = true >
class TypeValuesHelper
+ : public ParamValue<typename LLTypeTags::Sorted<T>::value_t>
{
+ typedef TypeValuesHelper<T, DERIVED_TYPE, IS_SPECIALIZED> self_t;
public:
typedef typename std::map<std::string, T> value_name_map_t;
typedef std::string name_t;
+ typedef self_t type_value_t;
+ typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t> param_value_t;
+ typedef typename param_value_t::value_t value_t;
+
+ TypeValuesHelper(const typename param_value_t::value_t& val)
+ : param_value_t(val)
+ {}
//TODO: cache key by index to save on param block size
void setValueName(const std::string& value_name)
@@ -130,7 +320,7 @@ namespace LLInitParam
return mValueName;
}
- std::string calcValueName(const T& value) const
+ std::string calcValueName(const value_t& value) const
{
value_name_map_t* map = getValueNames();
for (typename value_name_map_t::iterator it = map->begin(), end_it = map->end();
@@ -151,7 +341,7 @@ namespace LLInitParam
mValueName.clear();
}
- static bool getValueFromName(const std::string& name, T& value)
+ static bool getValueFromName(const std::string& name, value_t& value)
{
value_name_map_t* map = getValueNames();
typename value_name_map_t::iterator found_it = map->find(name);
@@ -193,18 +383,90 @@ namespace LLInitParam
return &sValues;
}
- static void declare(const std::string& name, const T& value)
+ static void declare(const std::string& name, const value_t& value)
{
(*getValueNames())[name] = value;
}
+ void operator ()(const std::string& name)
+ {
+ *this = name;
+ }
+
+ void assignNamedValue(const std::string& name)
+ {
+ if (getValueFromName(name, param_value_t::getValue()))
+ {
+ setValueName(name);
+ }
+ }
+
+ operator const value_t&() const
+ {
+ return param_value_t::getValue();
+ }
+
+ const value_t& operator()() const
+ {
+ return param_value_t::getValue();
+ }
+
protected:
- static void getName(const std::string& name, const T& value)
+ static void getName(const std::string& name, const value_t& value)
{}
mutable std::string mValueName;
};
+ // string types can support custom named values, but need
+ // to disambiguate in code between a string that is a named value
+ // and a string that is a name
+ template <typename DERIVED_TYPE>
+ class TypeValuesHelper<std::string, DERIVED_TYPE, true>
+ : public TypeValuesHelper<std::string, DERIVED_TYPE, false>
+ {
+ public:
+ typedef TypeValuesHelper<std::string, DERIVED_TYPE, true> self_t;
+ typedef TypeValuesHelper<std::string, DERIVED_TYPE, false> base_t;
+ typedef std::string value_t;
+ typedef std::string name_t;
+ typedef self_t type_value_t;
+
+ TypeValuesHelper(const std::string& val)
+ : TypeValuesHelper(val)
+ {}
+
+ void operator ()(const std::string& name)
+ {
+ *this = name;
+ }
+
+ self_t& operator =(const std::string& name)
+ {
+ if (base_t::getValueFromName(name, ParamValue<std::string>::getValue()))
+ {
+ base_t::setValueName(name);
+ }
+ else
+ {
+ ParamValue<std::string>::setValue(name);
+ }
+ return *this;
+ }
+
+ operator const value_t&() const
+ {
+ return ParamValue<std::string>::getValue();
+ }
+
+ const value_t& operator()() const
+ {
+ return ParamValue<std::string>::getValue();
+ }
+
+ };
+
+ // parser base class with mechanisms for registering readers/writers/inspectors of different types
class Parser
{
LOG_CLASS(Parser);
@@ -354,6 +616,7 @@ namespace LLInitParam
} EInitializationState;
void aggregateBlockData(BlockDescriptor& src_block_data);
+ void addParam(ParamDescriptorPtr param, const char* name);
typedef boost::unordered_map<const std::string, ParamDescriptorPtr> param_map_t;
typedef std::vector<ParamDescriptorPtr> param_list_t;
@@ -369,48 +632,58 @@ namespace LLInitParam
class BaseBlock* mCurrentBlockPtr; // pointer to block currently being constructed
};
- class BaseBlock
- {
- public:
//TODO: implement in terms of owned_ptr
template<typename T>
- class Lazy
+ class LazyValue
{
public:
- Lazy()
+ LazyValue()
: mPtr(NULL)
{}
- ~Lazy()
+ ~LazyValue()
{
delete mPtr;
}
- Lazy(const Lazy& other)
+ LazyValue(const T& value)
{
- if (other.mPtr)
+ mPtr = new T(value);
+ }
+
+ LazyValue(const LazyValue& other)
+ : mPtr(NULL)
{
- mPtr = new T(*other.mPtr);
+ *this = other;
}
- else
+
+ LazyValue& operator = (const LazyValue& other)
+ {
+ if (!other.mPtr)
{
+ delete mPtr;
mPtr = NULL;
}
- }
-
- Lazy<T>& operator = (const Lazy<T>& other)
+ else
{
- if (other.mPtr)
+ if (!mPtr)
{
mPtr = new T(*other.mPtr);
}
else
{
- mPtr = NULL;
+ *mPtr = *(other.mPtr);
+ }
}
return *this;
}
+ bool operator==(const LazyValue& other) const
+ {
+ if (empty() || other.empty()) return false;
+ return *mPtr == *other.mPtr;
+ }
+
bool empty() const
{
return mPtr == NULL;
@@ -418,18 +691,29 @@ namespace LLInitParam
void set(const T& other)
{
- delete mPtr;
+ if (!mPtr)
+ {
mPtr = new T(other);
}
+ else
+ {
+ *mPtr = other;
+ }
+ }
const T& get() const
{
- return ensureInstance();
+ return *ensureInstance();
}
T& get()
{
- return ensureInstance();
+ return *ensureInstance();
+ }
+
+ operator const T&() const
+ {
+ return get();
}
private:
@@ -444,13 +728,50 @@ namespace LLInitParam
}
private:
- // if you get a compilation error with this, that means you are using a forward declared struct for T
- // unfortunately, the type traits we rely on don't work with forward declared typed
- //static const int dummy = sizeof(T);
mutable T* mPtr;
};
+ // root class of all parameter blocks
+
+ class BaseBlock
+ {
+ public:
+ // lift block tags into baseblock namespace so derived classes do not need to qualify them
+ typedef LLInitParam::IS_A_BLOCK IS_A_BLOCK;
+ typedef LLInitParam::NOT_BLOCK NOT_A_BLOCK;
+
+ template<typename T>
+ struct Sequential : public LLTypeTags::TypeTagBase<T, 2>
+ {
+ template <typename S> struct Cons { typedef Sequential<ParamValue<S> > value_t; };
+ template <typename S> struct Cons<Sequential<S> > { typedef Sequential<S> value_t; };
+ };
+
+ template<typename T>
+ struct Atomic : public LLTypeTags::TypeTagBase<T, 1>
+ {
+ template <typename S> struct Cons { typedef Atomic<ParamValue<S> > value_t; };
+ template <typename S> struct Cons<Atomic<S> > { typedef Atomic<S> value_t; };
+ };
+
+ template<typename T, typename BLOCK_T = typename IsBlock<T>::value_t >
+ struct Lazy : public LLTypeTags::TypeTagBase<T, 0>
+ {
+ template <typename S> struct Cons
+ {
+ typedef Lazy<ParamValue<S, BLOCK_T>, BLOCK_T> value_t;
+ };
+ template <typename S> struct Cons<Lazy<S, IS_A_BLOCK> >
+ {
+ typedef Lazy<S, IS_A_BLOCK> value_t;
+ };
+ template <typename S> struct Cons<Lazy<S, NOT_A_BLOCK> >
+ {
+ typedef Lazy<S, BLOCK_T> value_t;
+ };
+ };
+
// "Multiple" constraint types, put here in root class to avoid ambiguity during use
struct AnyAmount
{
@@ -520,8 +841,8 @@ namespace LLInitParam
void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const;
- virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
- virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
+ virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); }
+ virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }
// take all provided params from other and apply to self
bool overwriteFrom(const BaseBlock& other)
@@ -535,10 +856,17 @@ namespace LLInitParam
return false;
}
- static void addParam(BlockDescriptor& block_data, ParamDescriptorPtr param, const char* name);
-
ParamDescriptorPtr findParamDescriptor(const Param& param);
+ // take all provided params from other and apply to self
+ bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite);
+
+ static BlockDescriptor& getBlockDescriptor()
+ {
+ static BlockDescriptor sBlockDescriptor;
+ return sBlockDescriptor;
+ }
+
protected:
void init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size);
@@ -547,25 +875,11 @@ namespace LLInitParam
{
return mergeBlock(block_data, source, overwrite);
}
- // take all provided params from other and apply to self
- bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite);
-
- static BlockDescriptor& selfBlockDescriptor()
- {
- static BlockDescriptor sBlockDescriptor;
- return sBlockDescriptor;
- }
private:
const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;
};
- template<typename T>
- struct ParamCompare<BaseBlock::Lazy<T>, false >
- {
- static bool equals(const BaseBlock::Lazy<T>& a, const BaseBlock::Lazy<T>& b) { return !a.empty() || !b.empty(); }
- };
-
class Param
{
public:
@@ -605,240 +919,45 @@ namespace LLInitParam
};
- // these templates allow us to distinguish between template parameters
- // that derive from BaseBlock and those that don't
- template<typename T, typename Void = void>
- struct IsBlock
- {
- static const bool value = false;
- struct EmptyBase {};
- typedef EmptyBase base_class_t;
- };
-
- template<typename T>
- struct IsBlock<T, typename T::baseblock_base_class_t>
- {
- static const bool value = true;
- typedef BaseBlock base_class_t;
- };
-
- template<typename T>
- struct IsBlock<BaseBlock::Lazy<T>, typename T::baseblock_base_class_t >
- {
- static const bool value = true;
- typedef BaseBlock base_class_t;
- };
-
- template<typename T, typename NAME_VALUE_LOOKUP, bool VALUE_IS_BLOCK = IsBlock<T>::value>
- class ParamValue : public NAME_VALUE_LOOKUP
- {
- public:
- typedef const T& value_assignment_t;
- typedef T value_t;
- typedef ParamValue<T, NAME_VALUE_LOOKUP, VALUE_IS_BLOCK> self_t;
-
- ParamValue(): mValue() {}
- ParamValue(value_assignment_t other) : mValue(other) {}
-
- void setValue(value_assignment_t val)
- {
- mValue = val;
- }
-
- value_assignment_t getValue() const
- {
- return mValue;
- }
-
- T& getValue()
- {
- return mValue;
- }
-
- operator value_assignment_t() const
- {
- return mValue;
- }
-
- value_assignment_t operator()() const
- {
- return mValue;
- }
-
- void operator ()(const typename NAME_VALUE_LOOKUP::name_t& name)
- {
- *this = name;
- }
-
- self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
- {
- if (NAME_VALUE_LOOKUP::getValueFromName(name, mValue))
- {
- setValueName(name);
- }
-
- return *this;
- }
-
- protected:
- T mValue;
- };
-
- template<typename T, typename NAME_VALUE_LOOKUP>
- class ParamValue<T, NAME_VALUE_LOOKUP, true>
- : public T,
- public NAME_VALUE_LOOKUP
- {
- public:
- typedef const T& value_assignment_t;
- typedef T value_t;
- typedef ParamValue<T, NAME_VALUE_LOOKUP, true> self_t;
-
- ParamValue()
- : T(),
- mValidated(false)
- {}
-
- ParamValue(value_assignment_t other)
- : T(other),
- mValidated(false)
- {}
-
- void setValue(value_assignment_t val)
- {
- *this = val;
- }
-
- value_assignment_t getValue() const
- {
- return *this;
- }
-
- T& getValue()
- {
- return *this;
- }
-
- operator value_assignment_t() const
- {
- return *this;
- }
-
- value_assignment_t operator()() const
- {
- return *this;
- }
-
- void operator ()(const typename NAME_VALUE_LOOKUP::name_t& name)
- {
- *this = name;
- }
-
- self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
- {
- if (NAME_VALUE_LOOKUP::getValueFromName(name, *this))
- {
- setValueName(name);
- }
-
- return *this;
- }
-
- protected:
- mutable bool mValidated; // lazy validation flag
- };
-
- template<typename NAME_VALUE_LOOKUP>
- class ParamValue<std::string, NAME_VALUE_LOOKUP, false>
- : public NAME_VALUE_LOOKUP
- {
- public:
- typedef const std::string& value_assignment_t;
- typedef std::string value_t;
- typedef ParamValue<std::string, NAME_VALUE_LOOKUP, false> self_t;
-
- ParamValue(): mValue() {}
- ParamValue(value_assignment_t other) : mValue(other) {}
-
- void setValue(value_assignment_t val)
- {
- if (NAME_VALUE_LOOKUP::getValueFromName(val, mValue))
- {
- NAME_VALUE_LOOKUP::setValueName(val);
- }
- else
- {
- mValue = val;
- }
- }
-
- value_assignment_t getValue() const
- {
- return mValue;
- }
-
- std::string& getValue()
- {
- return mValue;
- }
-
- operator value_assignment_t() const
- {
- return mValue;
- }
-
- value_assignment_t operator()() const
- {
- return mValue;
- }
-
- protected:
- std::string mValue;
- };
-
-
template<typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
struct ParamIterator
{
- typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::const_iterator const_iterator;
- typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::iterator iterator;
+ typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t >::const_iterator const_iterator;
+ typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t >::iterator iterator;
};
- // specialize for custom parsing/decomposition of specific classes
- // e.g. TypedParam<LLRect> has left, top, right, bottom, etc...
+ // wrapper for parameter with a known type
+ // specialized to handle 4 cases:
+ // simple "scalar" value
+ // parameter that is itself a block
+ // multiple scalar values, stored in a vector
+ // multiple blocks, stored in a vector
template<typename T,
typename NAME_VALUE_LOOKUP = TypeValues<T>,
bool HAS_MULTIPLE_VALUES = false,
- bool VALUE_IS_BLOCK = IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>
+ typename VALUE_IS_BLOCK = typename IsBlock<ParamValue<typename LLTypeTags::Sorted<T>::value_t> >::value_t>
class TypedParam
: public Param,
- public ParamValue<T, NAME_VALUE_LOOKUP>
+ public NAME_VALUE_LOOKUP::type_value_t
{
+ protected:
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK> self_t;
+ typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t> param_value_t;
+ typedef typename param_value_t::default_value_t default_value_t;
+ typedef typename NAME_VALUE_LOOKUP::type_value_t named_value_t;
public:
- typedef TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK> self_t;
- typedef ParamValue<T, NAME_VALUE_LOOKUP> param_value_t;
- typedef typename param_value_t::value_assignment_t value_assignment_t;
- typedef NAME_VALUE_LOOKUP name_value_lookup_t;
+ typedef typename param_value_t::value_t value_t;
- using param_value_t::operator();
+ using named_value_t::operator();
- TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
- : Param(block_descriptor.mCurrentBlockPtr)
+ TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+ : Param(block_descriptor.mCurrentBlockPtr),
+ named_value_t(value)
{
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
- ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
- block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
- &mergeWith,
- &deserializeParam,
- &serializeParam,
- validate_func,
- &inspectParam,
- min_count, max_count));
- BaseBlock::addParam(block_descriptor, param_descriptor, name);
+ init(block_descriptor, validate_func, min_count, max_count, name);
}
-
- setValue(value);
}
bool isProvided() const { return Param::anyProvided(); }
@@ -857,14 +976,15 @@ namespace LLInitParam
}
// try to parse a known named value
- if(name_value_lookup_t::valueNamesExist())
+ if(named_value_t::valueNamesExist())
{
// try to parse a known named value
std::string name;
if (parser.readValue(name))
{
// try to parse a per type named value
- if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
+
+ if (named_value_t::getValueFromName(name, typed_param.getValue()))
{
typed_param.setValueName(name);
typed_param.setProvided();
@@ -917,22 +1037,23 @@ namespace LLInitParam
// tell parser about our actual type
parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
// then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
- if (name_value_lookup_t::getPossibleValues())
+ if (named_value_t::getPossibleValues())
{
- parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());
+ parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
}
}
- void set(value_assignment_t val, bool flag_as_provided = true)
+ void set(const value_t& val, bool flag_as_provided = true)
{
- param_value_t::clearValueName();
+ named_value_t::clearValueName();
setValue(val);
setProvided(flag_as_provided);
}
- self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
+ self_t& operator =(const typename named_value_t::name_t& name)
{
- return static_cast<self_t&>(param_value_t::operator =(name));
+ named_value_t::assignNamedValue(name);
+ return *this;
}
protected:
@@ -957,37 +1078,43 @@ namespace LLInitParam
}
return false;
}
+ private:
+ void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )
+ {
+ ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+ block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ &mergeWith,
+ &deserializeParam,
+ &serializeParam,
+ validate_func,
+ &inspectParam,
+ min_count, max_count));
+ block_descriptor.addParam(param_descriptor, name);
+ }
};
// parameter that is a block
template <typename T, typename NAME_VALUE_LOOKUP>
- class TypedParam<T, NAME_VALUE_LOOKUP, false, true>
+ class TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK>
: public Param,
- public ParamValue<T, NAME_VALUE_LOOKUP>
+ public NAME_VALUE_LOOKUP::type_value_t
{
+ protected:
+ typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t> param_value_t;
+ typedef typename param_value_t::default_value_t default_value_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK> self_t;
+ typedef typename NAME_VALUE_LOOKUP::type_value_t named_value_t;
public:
- typedef ParamValue<T, NAME_VALUE_LOOKUP> param_value_t;
- typedef typename param_value_t::value_assignment_t value_assignment_t;
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, true> self_t;
- typedef NAME_VALUE_LOOKUP name_value_lookup_t;
-
- using param_value_t::operator();
+ using named_value_t::operator();
+ typedef typename param_value_t::value_t value_t;
- TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+ TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
: Param(block_descriptor.mCurrentBlockPtr),
- param_value_t(value)
+ named_value_t(value)
{
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
- ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
- block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
- &mergeWith,
- &deserializeParam,
- &serializeParam,
- validate_func,
- &inspectParam,
- min_count, max_count));
- BaseBlock::addParam(block_descriptor, param_descriptor, name);
+ init(block_descriptor, validate_func, min_count, max_count, name);
}
}
@@ -1002,14 +1129,14 @@ namespace LLInitParam
return true;
}
- if(name_value_lookup_t::valueNamesExist())
+ if(named_value_t::valueNamesExist())
{
// try to parse a known named value
std::string name;
if (parser.readValue(name))
{
// try to parse a per type named value
- if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
+ if (named_value_t::getValueFromName(name, typed_param.getValue()))
{
typed_param.setValueName(name);
typed_param.setProvided();
@@ -1034,9 +1161,9 @@ namespace LLInitParam
std::string key = typed_param.getValueName();
if (!key.empty())
{
- if (!parser.writeValue(key, name_stack))
+ if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))
{
- return;
+ parser.writeValue(key, name_stack);
}
}
else
@@ -1047,8 +1174,16 @@ namespace LLInitParam
static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
{
- // I am a param that is also a block, so just recurse into my contents
const self_t& typed_param = static_cast<const self_t&>(param);
+
+ // tell parser about our actual type
+ parser.inspectValue<value_t>(name_stack, min_count, max_count, NULL);
+ // then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
+ if (named_value_t::getPossibleValues())
+ {
+ parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
+ }
+
typed_param.inspectBlock(parser, name_stack, min_count, max_count);
}
@@ -1066,32 +1201,34 @@ namespace LLInitParam
}
// assign block contents to this param-that-is-a-block
- void set(value_assignment_t val, bool flag_as_provided = true)
+ void set(const value_t& val, bool flag_as_provided = true)
{
setValue(val);
- param_value_t::clearValueName();
+ named_value_t::clearValueName();
// force revalidation of block
// next call to isProvided() will update provision status based on validity
param_value_t::mValidated = false;
setProvided(flag_as_provided);
}
- self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
+ self_t& operator =(const typename named_value_t::name_t& name)
{
- return static_cast<self_t&>(param_value_t::operator =(name));
+ named_value_t::assignNamedValue(name);
+ return *this;
}
// propagate changed status up to enclosing block
/*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
{
param_value_t::paramChanged(changed_param, user_provided);
+
if (user_provided)
{
// a child param has been explicitly changed
// so *some* aspect of this block is now provided
param_value_t::mValidated = false;
setProvided();
- param_value_t::clearValueName();
+ named_value_t::clearValueName();
}
else
{
@@ -1115,7 +1252,7 @@ namespace LLInitParam
if (src_typed_param.anyProvided())
{
- if (dst_typed_param.mergeBlockParam(src_typed_param.isProvided(), dst_typed_param.isProvided(), param_value_t::selfBlockDescriptor(), src_typed_param, overwrite))
+ if (dst_typed_param.mergeBlockParam(src_typed_param.isProvided(), dst_typed_param.isProvided(), param_value_t::getBlockDescriptor(), src_typed_param, overwrite))
{
dst_typed_param.clearValueName();
dst_typed_param.setProvided(true);
@@ -1124,38 +1261,46 @@ namespace LLInitParam
}
return false;
}
+
+ private:
+ void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )
+ {
+ ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+ block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ &mergeWith,
+ &deserializeParam,
+ &serializeParam,
+ validate_func,
+ &inspectParam,
+ min_count, max_count));
+ block_descriptor.addParam(param_descriptor, name);
+ }
};
// container of non-block parameters
template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
- class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false>
+ class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK>
: public Param
{
+ protected:
+ typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK> self_t;
+ typedef ParamValue<typename LLTypeTags::Sorted<VALUE_TYPE>::value_t> param_value_t;
+ typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t> container_t;
+ typedef container_t default_value_t;
+ typedef typename NAME_VALUE_LOOKUP::type_value_t named_value_t;
+
public:
- typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false> self_t;
- typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP> param_value_t;
- typedef typename std::vector<param_value_t> container_t;
- typedef const container_t& value_assignment_t;
-
typedef typename param_value_t::value_t value_t;
- typedef NAME_VALUE_LOOKUP name_value_lookup_t;
- TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+ TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
: Param(block_descriptor.mCurrentBlockPtr)
{
std::copy(value.begin(), value.end(), std::back_inserter(mValues));
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
- ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
- block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
- &mergeWith,
- &deserializeParam,
- &serializeParam,
- validate_func,
- &inspectParam,
- min_count, max_count));
- BaseBlock::addParam(block_descriptor, param_descriptor, name);
+ init(block_descriptor, validate_func, min_count, max_count, name);
+
}
}
@@ -1176,14 +1321,14 @@ namespace LLInitParam
}
// try to parse a known named value
- if(name_value_lookup_t::valueNamesExist())
+ if(named_value_t::valueNamesExist())
{
// try to parse a known named value
std::string name;
if (parser.readValue(name))
{
// try to parse a per type named value
- if (name_value_lookup_t::getValueFromName(name, value))
+ if (named_value_t::getValueFromName(name, value))
{
typed_param.add(value);
typed_param.mValues.back().setValueName(name);
@@ -1234,13 +1379,13 @@ namespace LLInitParam
static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
{
parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL);
- if (name_value_lookup_t::getPossibleValues())
+ if (named_value_t::getPossibleValues())
{
- parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());
+ parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
}
}
- void set(value_assignment_t val, bool flag_as_provided = true)
+ void set(const container_t& val, bool flag_as_provided = true)
{
mValues = val;
setProvided(flag_as_provided);
@@ -1248,26 +1393,24 @@ namespace LLInitParam
param_value_t& add()
{
- mValues.push_back(param_value_t(value_t()));
+ mValues.push_back(value_t());
Param::setProvided();
return mValues.back();
}
self_t& add(const value_t& item)
{
- param_value_t param_value;
- param_value.setValue(item);
- mValues.push_back(param_value);
+ mValues.push_back(item);
setProvided();
return *this;
}
- self_t& add(const typename name_value_lookup_t::name_t& name)
+ self_t& add(const typename named_value_lookup_t::name_t& name)
{
value_t value;
// try to parse a per type named value
- if (name_value_lookup_t::getValueFromName(name, value))
+ if (named_value_t::getValueFromName(name, value))
{
add(value);
mValues.back().setValueName(name);
@@ -1277,9 +1420,9 @@ namespace LLInitParam
}
// implicit conversion
- operator value_assignment_t() const { return mValues; }
+ operator const container_t&() const { return mValues; }
// explicit conversion
- value_assignment_t operator()() const { return mValues; }
+ const container_t& operator()() const { return mValues; }
typedef typename container_t::iterator iterator;
typedef typename container_t::const_iterator const_iterator;
@@ -1320,37 +1463,46 @@ namespace LLInitParam
}
container_t mValues;
+
+ private:
+ void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )
+ {
+ ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+ block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ &mergeWith,
+ &deserializeParam,
+ &serializeParam,
+ validate_func,
+ &inspectParam,
+ min_count, max_count));
+ block_descriptor.addParam(param_descriptor, name);
+ }
};
// container of block parameters
template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
- class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true>
+ class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK>
: public Param
{
+ protected:
+ typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK> self_t;
+ typedef ParamValue<typename LLTypeTags::Sorted<VALUE_TYPE>::value_t> param_value_t;
+ typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t> container_t;
+ typedef typename NAME_VALUE_LOOKUP::type_value_t named_value_t;
+ typedef container_t default_value_t;
+ typedef typename container_t::iterator iterator;
+ typedef typename container_t::const_iterator const_iterator;
public:
- typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true> self_t;
- typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP> param_value_t;
- typedef typename std::vector<param_value_t> container_t;
- typedef const container_t& value_assignment_t;
typedef typename param_value_t::value_t value_t;
- typedef NAME_VALUE_LOOKUP name_value_lookup_t;
- TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+ TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
: Param(block_descriptor.mCurrentBlockPtr)
{
std::copy(value.begin(), value.end(), back_inserter(mValues));
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
- ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
- block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
- &mergeWith,
- &deserializeParam,
- &serializeParam,
- validate_func,
- &inspectParam,
- min_count, max_count));
- BaseBlock::addParam(block_descriptor, param_descriptor, name);
+ init(block_descriptor, validate_func, min_count, max_count, name);
}
}
@@ -1375,14 +1527,14 @@ namespace LLInitParam
typed_param.setProvided();
return true;
}
- else if(name_value_lookup_t::valueNamesExist())
+ else if(named_value_t::valueNamesExist())
{
// try to parse a known named value
std::string name;
if (parser.readValue(name))
{
// try to parse a per type named value
- if (name_value_lookup_t::getValueFromName(name, value.getValue()))
+ if (named_value_t::getValueFromName(name, value.getValue()))
{
typed_param.mValues.back().setValueName(name);
typed_param.setProvided();
@@ -1427,11 +1579,20 @@ namespace LLInitParam
static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
{
- // I am a vector of blocks, so describe my contents recursively
- param_value_t(value_t()).inspectBlock(parser, name_stack, min_count, max_count);
+ const param_value_t& value_param = param_value_t(value_t());
+
+ // tell parser about our actual type
+ parser.inspectValue<value_t>(name_stack, min_count, max_count, NULL);
+ // then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
+ if (named_value_t::getPossibleValues())
+ {
+ parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
+ }
+
+ value_param.inspectBlock(parser, name_stack, min_count, max_count);
}
- void set(value_assignment_t val, bool flag_as_provided = true)
+ void set(const container_t& val, bool flag_as_provided = true)
{
mValues = val;
setProvided(flag_as_provided);
@@ -1451,12 +1612,12 @@ namespace LLInitParam
return *this;
}
- self_t& add(const typename name_value_lookup_t::name_t& name)
+ self_t& add(const typename named_value_lookup_t::name_t& name)
{
value_t value;
// try to parse a per type named value
- if (name_value_lookup_t::getValueFromName(name, value))
+ if (named_value_t::getValueFromName(name, value))
{
add(value);
mValues.back().setValueName(name);
@@ -1465,12 +1626,10 @@ namespace LLInitParam
}
// implicit conversion
- operator value_assignment_t() const { return mValues; }
+ operator const container_t&() const { return mValues; }
// explicit conversion
- value_assignment_t operator()() const { return mValues; }
+ const container_t& operator()() const { return mValues; }
- typedef typename container_t::iterator iterator;
- typedef typename container_t::const_iterator const_iterator;
iterator begin() { return mValues.begin(); }
iterator end() { return mValues.end(); }
const_iterator begin() const { return mValues.begin(); }
@@ -1517,6 +1676,20 @@ namespace LLInitParam
}
container_t mValues;
+
+ private:
+ void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )
+ {
+ ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+ block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ &mergeWith,
+ &deserializeParam,
+ &serializeParam,
+ validate_func,
+ &inspectParam,
+ min_count, max_count));
+ block_descriptor.addParam(param_descriptor, name);
+ }
};
template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
@@ -1531,13 +1704,13 @@ namespace LLInitParam
// take all provided params from other and apply to self
bool overwriteFrom(const self_t& other)
{
- return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, true);
+ return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, true);
}
// take all provided params that are not already provided, and apply to self
bool fillFrom(const self_t& other)
{
- return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, false);
+ return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, false);
}
bool mergeBlockParam(bool source_provided, bool dest_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
@@ -1555,7 +1728,7 @@ namespace LLInitParam
bool mergeBlock(BlockDescriptor& block_data, const self_t& other, bool overwrite)
{
mCurChoice = other.mCurChoice;
- return base_block_t::mergeBlock(selfBlockDescriptor(), other, overwrite);
+ return base_block_t::mergeBlock(getBlockDescriptor(), other, overwrite);
}
// clear out old choice when param has changed
@@ -1576,38 +1749,38 @@ namespace LLInitParam
base_block_t::paramChanged(changed_param, user_provided);
}
- virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
- virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
+ virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); }
+ virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }
protected:
ChoiceBlock()
: mCurChoice(0)
{
- BaseBlock::init(selfBlockDescriptor(), base_block_t::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
+ BaseBlock::init(getBlockDescriptor(), base_block_t::getBlockDescriptor(), sizeof(DERIVED_BLOCK));
}
// Alternatives are mutually exclusive wrt other Alternatives in the same block.
// One alternative in a block will always have isChosen() == true.
// At most one alternative in a block will have isProvided() == true.
- template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+ template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >
class Alternative : public TypedParam<T, NAME_VALUE_LOOKUP, false>
{
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false> super_t;
+ typedef typename super_t::value_t value_t;
+ typedef typename super_t::default_value_t default_value_t;
+
public:
friend class ChoiceBlock<DERIVED_BLOCK>;
- typedef Alternative<T, NAME_VALUE_LOOKUP> self_t;
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
- typedef typename super_t::value_assignment_t value_assignment_t;
-
using super_t::operator =;
- explicit Alternative(const char* name = "", value_assignment_t val = defaultValue<T>())
- : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1),
+ explicit Alternative(const char* name = "", const default_value_t& val = defaultValue<default_value_t>())
+ : super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, NULL, 0, 1),
mOriginalValue(val)
{
// assign initial choice to first declared option
- DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr);
- if (LL_UNLIKELY(DERIVED_BLOCK::selfBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))
+ DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::getBlockDescriptor().mCurrentBlockPtr);
+ if (LL_UNLIKELY(DERIVED_BLOCK::getBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))
{
if(blockp->mCurChoice == 0)
{
@@ -1621,27 +1794,27 @@ namespace LLInitParam
static_cast<enclosing_block_t&>(Param::enclosingBlock()).paramChanged(*this, true);
}
- void chooseAs(value_assignment_t val)
+ void chooseAs(const value_t& val)
{
super_t::set(val);
}
- void operator =(value_assignment_t val)
+ void operator =(const value_t& val)
{
super_t::set(val);
}
- void operator()(typename super_t::value_assignment_t val)
+ void operator()(const value_t& val)
{
super_t::set(val);
}
- operator value_assignment_t() const
+ operator const value_t&() const
{
return (*this)();
}
- value_assignment_t operator()() const
+ const value_t& operator()() const
{
if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)
{
@@ -1656,11 +1829,11 @@ namespace LLInitParam
}
private:
- T mOriginalValue;
+ default_value_t mOriginalValue;
};
- protected:
- static BlockDescriptor& selfBlockDescriptor()
+ public:
+ static BlockDescriptor& getBlockDescriptor()
{
static BlockDescriptor sBlockDescriptor;
return sBlockDescriptor;
@@ -1680,6 +1853,8 @@ namespace LLInitParam
: public BASE_BLOCK
{
typedef Block<DERIVED_BLOCK, BASE_BLOCK> self_t;
+
+ protected:
typedef Block<DERIVED_BLOCK, BASE_BLOCK> block_t;
public:
@@ -1688,80 +1863,82 @@ namespace LLInitParam
// take all provided params from other and apply to self
bool overwriteFrom(const self_t& other)
{
- return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, true);
+ return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, true);
}
// take all provided params that are not already provided, and apply to self
bool fillFrom(const self_t& other)
{
- return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, false);
+ return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, false);
}
- virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
- virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
+ virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); }
+ virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }
protected:
Block()
{
//#pragma message("Parsing LLInitParam::Block")
- BaseBlock::init(selfBlockDescriptor(), BASE_BLOCK::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
+ BaseBlock::init(getBlockDescriptor(), BASE_BLOCK::getBlockDescriptor(), sizeof(DERIVED_BLOCK));
}
//
// Nested classes for declaring parameters
//
- template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+ template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >
class Optional : public TypedParam<T, NAME_VALUE_LOOKUP, false>
{
- public:
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
- typedef typename super_t::value_assignment_t value_assignment_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false> super_t;
+ typedef typename super_t::value_t value_t;
+ typedef typename super_t::default_value_t default_value_t;
+ public:
using super_t::operator();
using super_t::operator =;
- explicit Optional(const char* name = "", value_assignment_t val = defaultValue<T>())
- : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1)
+ explicit Optional(const char* name = "", const default_value_t& val = defaultValue<default_value_t>())
+ : super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, NULL, 0, 1)
{
//#pragma message("Parsing LLInitParam::Block::Optional")
}
- Optional& operator =(value_assignment_t val)
+ Optional& operator =(const value_t& val)
{
set(val);
return *this;
}
- DERIVED_BLOCK& operator()(value_assignment_t val)
+ DERIVED_BLOCK& operator()(const value_t& val)
{
super_t::set(val);
return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
}
};
- template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+ template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >
class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>
{
- public:
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false> super_t;
typedef Mandatory<T, NAME_VALUE_LOOKUP> self_t;
- typedef typename super_t::value_assignment_t value_assignment_t;
+ typedef typename super_t::value_t value_t;
+ typedef typename super_t::default_value_t default_value_t;
+ public:
using super_t::operator();
using super_t::operator =;
// mandatory parameters require a name to be parseable
- explicit Mandatory(const char* name = "", value_assignment_t val = defaultValue<T>())
- : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, 1, 1)
+ explicit Mandatory(const char* name = "", const default_value_t& val = defaultValue<default_value_t>())
+ : super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, &validate, 1, 1)
{}
- Mandatory& operator =(value_assignment_t val)
+ Mandatory& operator =(const value_t& val)
{
set(val);
return *this;
}
- DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)
+ DERIVED_BLOCK& operator()(const value_t& val)
{
super_t::set(val);
return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
@@ -1775,28 +1952,29 @@ namespace LLInitParam
};
- template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+ template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >
class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>
{
- public:
- typedef TypedParam<T, NAME_VALUE_LOOKUP, true, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, true> super_t;
typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP> self_t;
typedef typename super_t::container_t container_t;
- typedef typename super_t::value_assignment_t value_assignment_t;
+ typedef typename super_t::value_t value_t;
+
+ public:
typedef typename super_t::iterator iterator;
typedef typename super_t::const_iterator const_iterator;
explicit Multiple(const char* name = "")
- : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
+ : super_t(DERIVED_BLOCK::getBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
{}
- Multiple& operator =(value_assignment_t val)
+ Multiple& operator =(const container_t& val)
{
set(val);
return *this;
}
- DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)
+ DERIVED_BLOCK& operator()(const container_t& val)
{
super_t::set(val);
return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
@@ -1813,9 +1991,9 @@ namespace LLInitParam
{
public:
explicit Deprecated(const char* name)
- : Param(DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr)
+ : Param(DERIVED_BLOCK::getBlockDescriptor().mCurrentBlockPtr)
{
- BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor();
+ BlockDescriptor& block_descriptor = DERIVED_BLOCK::getBlockDescriptor();
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
@@ -1826,7 +2004,7 @@ namespace LLInitParam
NULL,
NULL,
0, S32_MAX));
- BaseBlock::addParam(block_descriptor, param_descriptor, name);
+ block_descriptor.addParam(param_descriptor, name);
}
}
@@ -1846,16 +2024,17 @@ namespace LLInitParam
// different semantics for documentation purposes, but functionally identical
typedef Deprecated Ignored;
- protected:
- static BlockDescriptor& selfBlockDescriptor()
+ public:
+ static BlockDescriptor& getBlockDescriptor()
{
static BlockDescriptor sBlockDescriptor;
return sBlockDescriptor;
}
- template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, bool is_block>
+ protected:
+ template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, typename is_block>
void changeDefault(TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>& param,
- typename TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>::value_assignment_t value)
+ const typename TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>::value_t& value)
{
if (!param.isProvided())
{
@@ -1865,202 +2044,414 @@ namespace LLInitParam
};
- template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
- class BatchBlock
- : public Block<DERIVED_BLOCK, BASE_BLOCK>
+ template<typename T, typename BLOCK_T>
+ struct IsBlock<ParamValue<BaseBlock::Lazy<T, BaseBlock::IS_A_BLOCK>, BLOCK_T >, void>
+ {
+ typedef IS_A_BLOCK value_t;
+ };
+
+ template<typename T, typename BLOCK_T>
+ struct IsBlock<ParamValue<BaseBlock::Lazy<T, BaseBlock::NOT_A_BLOCK>, BLOCK_T >, void>
+ {
+ typedef NOT_BLOCK value_t;
+ };
+
+ template<typename T, typename BLOCK_IDENTIFIER>
+ struct IsBlock<ParamValue<BaseBlock::Atomic<T>, typename IsBlock<BaseBlock::Atomic<T> >::value_t >, BLOCK_IDENTIFIER>
+ {
+ typedef typename IsBlock<T>::value_t value_t;
+ };
+
+ template<typename T, typename BLOCK_IDENTIFIER>
+ struct IsBlock<ParamValue<BaseBlock::Sequential<T>, typename IsBlock<BaseBlock::Sequential<T> >::value_t >, BLOCK_IDENTIFIER>
{
+ typedef typename IsBlock<T>::value_t value_t;
+ };
+
+
+ template<typename T>
+ struct InnerMostType
+ {
+ typedef T value_t;
+ };
+
+ template<typename T>
+ struct InnerMostType<ParamValue<T, NOT_BLOCK> >
+ {
+ typedef typename InnerMostType<T>::value_t value_t;
+ };
+
+ template<typename T>
+ struct InnerMostType<ParamValue<T, IS_A_BLOCK> >
+ {
+ typedef typename InnerMostType<T>::value_t value_t;
+ };
+
+ template<typename T, typename BLOCK_T>
+ class ParamValue <BaseBlock::Atomic<T>, BLOCK_T>
+ {
+ typedef ParamValue <BaseBlock::Atomic<T>, BLOCK_T> self_t;
+
public:
- typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> self_t;
- typedef Block<DERIVED_BLOCK, BASE_BLOCK> super_t;
+ typedef typename InnerMostType<T>::value_t value_t;
+ typedef T default_value_t;
- BatchBlock()
+ ParamValue()
+ : mValue(),
+ mValidated(false)
+ {}
+
+ ParamValue(const default_value_t& value)
+ : mValue(value),
+ mValidated(false)
{}
+ void setValue(const value_t& val)
+ {
+ mValue.setValue(val);
+ }
+
+ const value_t& getValue() const
+ {
+ return mValue.getValue();
+ }
+
+ value_t& getValue()
+ {
+ return mValue.getValue();
+ }
+
bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
{
if (new_name)
{
- // reset block
- *static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue();
+ resetToDefault();
+ }
+ return mValue.deserializeBlock(p, name_stack_range, new_name);
}
- return super_t::deserializeBlock(p, name_stack_range, new_name);
+
+ void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
+ {
+ const BaseBlock* base_block = diff_block
+ ? &(diff_block->mValue)
+ : NULL;
+ mValue.serializeBlock(p, name_stack, base_block);
+ }
+
+ bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
+ {
+ return mValue.inspectBlock(p, name_stack, min_count, max_count);
}
- bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
+ bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
{
if (overwrite)
{
- *static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue();
- // merge individual parameters into destination
- return super_t::mergeBlock(super_t::selfBlockDescriptor(), other, overwrite);
+ resetToDefault();
+ return mValue.mergeBlock(block_data, source.getValue(), overwrite);
}
return false;
}
- protected:
- static const DERIVED_BLOCK& defaultBatchValue()
+
+ bool validateBlock(bool emit_errors = true) const
+ {
+ return mValue.validateBlock(emit_errors);
+ }
+
+ static BlockDescriptor& getBlockDescriptor()
+ {
+ return value_t::getBlockDescriptor();
+ }
+
+
+ mutable bool mValidated; // lazy validation flag
+
+ private:
+ void resetToDefault()
{
- static DERIVED_BLOCK default_value;
- return default_value;
+ static T default_value;
+ mValue = default_value;
}
+
+ T mValue;
};
- // FIXME: this specialization is not currently used, as it only matches against the BatchBlock base class
- // and not the derived class with the actual params
- template<typename DERIVED_BLOCK,
- typename BASE_BLOCK,
- typename NAME_VALUE_LOOKUP>
- class ParamValue <BatchBlock<DERIVED_BLOCK, BASE_BLOCK>,
- NAME_VALUE_LOOKUP,
- true>
- : public NAME_VALUE_LOOKUP,
- protected BatchBlock<DERIVED_BLOCK, BASE_BLOCK>
+ template<typename T>
+ class ParamValue <BaseBlock::Sequential<T>, IS_A_BLOCK>
{
+ typedef ParamValue <BaseBlock::Sequential<T>, IS_A_BLOCK> self_t;
+
public:
- typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> block_t;
- typedef const BatchBlock<DERIVED_BLOCK, BASE_BLOCK>& value_assignment_t;
- typedef block_t value_t;
+ typedef typename InnerMostType<T>::value_t value_t;
+ typedef T default_value_t;
ParamValue()
- : block_t(),
+ : mValue(),
mValidated(false)
- {}
+ {
+ mCurParam = getBlockDescriptor().mAllParams.begin();
+ }
- ParamValue(value_assignment_t other)
- : block_t(other),
+ ParamValue(const default_value_t& value)
+ : mValue(value),
mValidated(false)
{
+ mCurParam = getBlockDescriptor().mAllParams.begin();
}
- void setValue(value_assignment_t val)
+ void setValue(const value_t& val)
{
- *this = val;
+ mValue.setValue(val);
}
- value_assignment_t getValue() const
+ const value_t& getValue() const
{
- return *this;
+ return mValue.getValue();
}
- BatchBlock<DERIVED_BLOCK, BASE_BLOCK>& getValue()
+ value_t& getValue()
{
- return *this;
+ return mValue.getValue();
}
- operator value_assignment_t() const
+ bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
{
- return *this;
+ if (new_name)
+ {
+ mCurParam = getBlockDescriptor().mAllParams.begin();
+ }
+ if (name_stack_range.first == name_stack_range.second
+ && mCurParam != getBlockDescriptor().mAllParams.end())
+ {
+ // deserialize to mCurParam
+ ParamDescriptor& pd = *(*mCurParam);
+ ParamDescriptor::deserialize_func_t deserialize_func = pd.mDeserializeFunc;
+ Param* paramp = mValue.getParamFromHandle(pd.mParamHandle);
+
+ if (deserialize_func
+ && paramp
+ && deserialize_func(*paramp, p, name_stack_range, new_name))
+ {
+ ++mCurParam;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return mValue.deserializeBlock(p, name_stack_range, new_name);
+ }
}
- value_assignment_t operator()() const
+ void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
{
- return *this;
+ const BaseBlock* base_block = diff_block
+ ? &(diff_block->mValue)
+ : NULL;
+ mValue.serializeBlock(p, name_stack, base_block);
+ }
+
+ bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
+ {
+ return mValue.inspectBlock(p, name_stack, min_count, max_count);
+ }
+
+ bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
+ {
+ return mValue.mergeBlock(block_data, source.getValue(), overwrite);
+ }
+
+ bool validateBlock(bool emit_errors = true) const
+ {
+ return mValue.validateBlock(emit_errors);
+ }
+
+ static BlockDescriptor& getBlockDescriptor()
+ {
+ return value_t::getBlockDescriptor();
}
- protected:
mutable bool mValidated; // lazy validation flag
+
+ private:
+
+ BlockDescriptor::all_params_list_t::iterator mCurParam;
+ T mValue;
};
- template<typename T, bool IS_BLOCK>
- class ParamValue <BaseBlock::Lazy<T>,
- TypeValues<T>,
- IS_BLOCK>
- : public IsBlock<T>::base_class_t
+ template<typename T>
+ class ParamValue <BaseBlock::Sequential<T>, NOT_BLOCK>
+ : public T
{
+ typedef ParamValue <BaseBlock::Sequential<T>, NOT_BLOCK> self_t;
+
public:
- typedef ParamValue <BaseBlock::Lazy<T>, TypeValues<T>, false> self_t;
- typedef const T& value_assignment_t;
- typedef T value_t;
+ typedef typename InnerMostType<T>::value_t value_t;
+ typedef T default_value_t;
+
+ ParamValue()
+ : T(),
+ mValidated(false)
+ {}
+
+ ParamValue(const default_value_t& value)
+ : T(value.getValue()),
+ mValidated(false)
+ {}
+
+ mutable bool mValidated; // lazy validation flag
+ };
+
+ template<typename T, typename BLOCK_T>
+ class ParamValue <BaseBlock::Lazy<T, IS_A_BLOCK>, BLOCK_T>
+ {
+ typedef ParamValue <BaseBlock::Lazy<T, IS_A_BLOCK>, BLOCK_T> self_t;
+
+ public:
+ typedef typename InnerMostType<T>::value_t value_t;
+ typedef LazyValue<T> default_value_t;
ParamValue()
: mValue(),
mValidated(false)
{}
- ParamValue(value_assignment_t other)
+ ParamValue(const default_value_t& other)
: mValue(other),
mValidated(false)
{}
- void setValue(value_assignment_t val)
+ ParamValue(const T& value)
+ : mValue(value),
+ mValidated(false)
+ {}
+
+ void setValue(const value_t& val)
{
mValue.set(val);
}
- value_assignment_t getValue() const
+ const value_t& getValue() const
{
- return mValue.get();
+ return mValue.get().getValue();
}
- T& getValue()
+ value_t& getValue()
+ {
+ return mValue.get().getValue();
+ }
+
+ bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
{
- return mValue.get();
+ return mValue.get().deserializeBlock(p, name_stack_range, new_name);
}
- operator value_assignment_t() const
+ void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
{
- return mValue.get();
+ if (mValue.empty()) return;
+
+ const BaseBlock* base_block = (diff_block && !diff_block->mValue.empty())
+ ? &(diff_block->mValue.get().getValue())
+ : NULL;
+ mValue.get().serializeBlock(p, name_stack, base_block);
}
- value_assignment_t operator()() const
+ bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
{
- return mValue.get();
+ return mValue.get().inspectBlock(p, name_stack, min_count, max_count);
}
- bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
+ bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
{
- return mValue.get().deserializeBlock(p, name_stack_range, new_name);
+ return source.mValue.empty() || mValue.get().mergeBlock(block_data, source.getValue(), overwrite);
}
- void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const
+ bool validateBlock(bool emit_errors = true) const
{
- if (mValue.empty()) return;
+ return mValue.empty() || mValue.get().validateBlock(emit_errors);
+ }
+
+ static BlockDescriptor& getBlockDescriptor()
+ {
+ return value_t::getBlockDescriptor();
+ }
+
+ mutable bool mValidated; // lazy validation flag
+
+ private:
+ LazyValue<T> mValue;
+ };
+
+ template<typename T, typename BLOCK_T>
+ class ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_T>
+ {
+ typedef ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_T> self_t;
+
+ public:
+ typedef typename InnerMostType<T>::value_t value_t;
+ typedef LazyValue<T> default_value_t;
+
+ ParamValue()
+ : mValue(),
+ mValidated(false)
+ {}
+
+ ParamValue(const default_value_t& other)
+ : mValue(other),
+ mValidated(false)
+ {}
+
+ ParamValue(const T& value)
+ : mValue(value),
+ mValidated(false)
+ {}
- mValue.get().serializeBlock(p, name_stack, diff_block);
+ void setValue(const value_t& val)
+ {
+ mValue.set(val);
}
- bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
+ const value_t& getValue() const
{
- if (mValue.empty()) return false;
+ return mValue.get().getValue();
+ }
- return mValue.get().inspectBlock(p, name_stack, min_count, max_count);
+ value_t& getValue()
+ {
+ return mValue.get().getValue();
}
- protected:
mutable bool mValidated; // lazy validation flag
private:
- BaseBlock::Lazy<T> mValue;
+ LazyValue<T> mValue;
};
template <>
- class ParamValue <LLSD,
- TypeValues<LLSD>,
- false>
- : public TypeValues<LLSD>,
- public BaseBlock
+ class ParamValue <LLSD, NOT_BLOCK>
+ : public BaseBlock
{
public:
- typedef ParamValue<LLSD, TypeValues<LLSD>, false> self_t;
- typedef const LLSD& value_assignment_t;
+ typedef LLSD value_t;
+ typedef LLSD default_value_t;
ParamValue()
: mValidated(false)
{}
- ParamValue(value_assignment_t other)
+ ParamValue(const default_value_t& other)
: mValue(other),
mValidated(false)
{}
- void setValue(value_assignment_t val) { mValue = val; }
+ void setValue(const value_t& val) { mValue = val; }
- value_assignment_t getValue() const { return mValue; }
+ const value_t& getValue() const { return mValue; }
LLSD& getValue() { return mValue; }
- operator value_assignment_t() const { return mValue; }
- value_assignment_t operator()() const { return mValue; }
-
-
// block param interface
bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
@@ -2081,8 +2472,7 @@ namespace LLInitParam
template<typename T>
class CustomParamValue
- : public Block<ParamValue<T, TypeValues<T> > >,
- public TypeValues<T>
+ : public Block<ParamValue<T> >
{
public:
typedef enum e_value_age
@@ -2092,14 +2482,15 @@ namespace LLInitParam
BLOCK_AUTHORITATIVE // mValue is derived from the block parameters, which are authoritative
} EValueAge;
- typedef ParamValue<T, TypeValues<T> > derived_t;
+ typedef ParamValue<T> derived_t;
typedef CustomParamValue<T> self_t;
typedef Block<derived_t> block_t;
- typedef const T& value_assignment_t;
+ typedef T default_value_t;
typedef T value_t;
+ typedef void baseblock_base_class_t;
- CustomParamValue(const T& value = T())
+ CustomParamValue(const default_value_t& value = T())
: mValue(value),
mValueAge(VALUE_AUTHORITATIVE),
mValidated(false)
@@ -2116,8 +2507,6 @@ namespace LLInitParam
typed_param.mValueAge = VALUE_AUTHORITATIVE;
typed_param.updateBlockFromValue(false);
- typed_param.clearValueName();
-
return true;
}
}
@@ -2131,18 +2520,8 @@ namespace LLInitParam
const derived_t& typed_param = static_cast<const derived_t&>(*this);
const derived_t* diff_param = static_cast<const derived_t*>(diff_block);
- std::string key = typed_param.getValueName();
-
- // first try to write out name of name/value pair
- if (!key.empty())
- {
- if (!diff_param || !ParamCompare<std::string>::equals(diff_param->getValueName(), key))
- {
- parser.writeValue(key, name_stack);
- }
- }
// then try to serialize value directly
- else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue()))
+ if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue()))
{
if (!parser.writeValue(typed_param.getValue(), name_stack))
@@ -2172,19 +2551,6 @@ namespace LLInitParam
}
}
- bool inspectBlock(Parser& parser, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
- {
- // first, inspect with actual type...
- parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
- if (TypeValues<T>::getPossibleValues())
- {
- //...then inspect with possible string values...
- parser.inspectValue<std::string>(name_stack, min_count, max_count, TypeValues<T>::getPossibleValues());
- }
- // then recursively inspect contents...
- return block_t::inspectBlock(parser, name_stack, min_count, max_count);
- }
-
bool validateBlock(bool emit_errors = true) const
{
if (mValueAge == VALUE_NEEDS_UPDATE)
@@ -2192,7 +2558,6 @@ namespace LLInitParam
if (block_t::validateBlock(emit_errors))
{
// clear stale keyword associated with old value
- TypeValues<T>::clearValueName();
mValueAge = BLOCK_AUTHORITATIVE;
static_cast<derived_t*>(const_cast<self_t*>(this))->updateValueFromBlock();
return true;
@@ -2222,17 +2587,15 @@ namespace LLInitParam
}
}
- void setValue(value_assignment_t val)
+ void setValue(const value_t& val)
{
- derived_t& typed_param = static_cast<derived_t&>(*this);
// set param version number to be up to date, so we ignore block contents
mValueAge = VALUE_AUTHORITATIVE;
mValue = val;
- typed_param.clearValueName();
static_cast<derived_t*>(this)->updateBlockFromValue(false);
}
- value_assignment_t getValue() const
+ const value_t& getValue() const
{
validateBlock(true);
return mValue;
@@ -2244,20 +2607,10 @@ namespace LLInitParam
return mValue;
}
- operator value_assignment_t() const
- {
- return getValue();
- }
-
- value_assignment_t operator()() const
- {
- return getValue();
- }
-
protected:
// use this from within updateValueFromBlock() to set the value without making it authoritative
- void updateValue(value_assignment_t value)
+ void updateValue(const value_t& value)
{
mValue = value;
}
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp
index afc76024d1..9cd88a1620 100644
--- a/indra/llxuixml/llxuiparser.cpp
+++ b/indra/llxuixml/llxuiparser.cpp
@@ -42,7 +42,7 @@
#include <boost/spirit/include/classic_core.hpp>
#include "lluicolor.h"
-
+#include "v3math.h"
using namespace BOOST_SPIRIT_CLASSIC_NS;
const S32 MAX_STRING_ATTRIBUTE_SIZE = 40;
@@ -79,7 +79,6 @@ struct Occurs : public LLInitParam::Block<Occurs>
{}
};
-
typedef enum
{
USE_REQUIRED,
@@ -101,14 +100,23 @@ namespace LLInitParam
struct Element;
struct Group;
-struct Choice;
struct Sequence;
-struct Any;
+
+struct All : public LLInitParam::Block<All, Occurs>
+{
+ Multiple< Lazy<Element, IS_A_BLOCK> > elements;
+
+ All()
+ : elements("element")
+ {
+ maxOccurs = 1;
+ }
+};
struct Attribute : public LLInitParam::Block<Attribute>
{
- Mandatory<std::string> name;
- Mandatory<std::string> type;
+ Mandatory<std::string> name,
+ type;
Mandatory<EUse> use;
Attribute()
@@ -127,24 +135,13 @@ struct Any : public LLInitParam::Block<Any, Occurs>
{}
};
-struct All : public LLInitParam::Block<All, Occurs>
-{
- Multiple< Lazy<Element> > elements;
-
- All()
- : elements("element")
- {
- maxOccurs = 1;
- }
-};
-
struct Choice : public LLInitParam::ChoiceBlock<Choice, Occurs>
{
- Alternative< Lazy<Element> > element;
- Alternative< Lazy<Group> > group;
- Alternative< Lazy<Choice> > choice;
- Alternative< Lazy<Sequence> > sequence;
- Alternative< Lazy<Any> > any;
+ Alternative< Lazy<Element, IS_A_BLOCK> > element;
+ Alternative< Lazy<Group, IS_A_BLOCK> > group;
+ Alternative< Lazy<Choice, IS_A_BLOCK> > choice;
+ Alternative< Lazy<Sequence, IS_A_BLOCK> > sequence;
+ Alternative< Lazy<Any> > any;
Choice()
: element("element"),
@@ -158,11 +155,11 @@ struct Choice : public LLInitParam::ChoiceBlock<Choice, Occurs>
struct Sequence : public LLInitParam::ChoiceBlock<Sequence, Occurs>
{
- Alternative< Lazy<Element> > element;
- Alternative< Lazy<Group> > group;
- Alternative< Lazy<Choice> > choice;
- Alternative< Lazy<Sequence> > sequence;
- Alternative< Lazy<Any> > any;
+ Alternative< Lazy<Element, IS_A_BLOCK> > element;
+ Alternative< Lazy<Group, IS_A_BLOCK> > group;
+ Alternative< Lazy<Choice> > choice;
+ Alternative< Lazy<Sequence, IS_A_BLOCK> > sequence;
+ Alternative< Lazy<Any> > any;
};
struct GroupContents : public LLInitParam::ChoiceBlock<GroupContents, Occurs>
@@ -247,7 +244,7 @@ struct ComplexType : public LLInitParam::Block<ComplexType, ComplexTypeContents>
Optional<bool> mixed;
Multiple<Attribute> attribute;
- Multiple< Lazy<Element> > elements;
+ Multiple< Lazy<Element, IS_A_BLOCK > > elements;
ComplexType()
: name("name"),
@@ -313,7 +310,6 @@ public:
setNameSpace(ns);
};
}
-
};
//
@@ -670,6 +666,7 @@ LLXUIParser::LLXUIParser()
registerParserFuncs<S32>(readS32Value, writeS32Value);
registerParserFuncs<F32>(readF32Value, writeF32Value);
registerParserFuncs<F64>(readF64Value, writeF64Value);
+ registerParserFuncs<LLVector3>(readVector3Value, writeVector3Value);
registerParserFuncs<LLColor4>(readColor4Value, writeColor4Value);
registerParserFuncs<LLUIColor>(readUIColorValue, writeUIColorValue);
registerParserFuncs<LLUUID>(readUUIDValue, writeUUIDValue);
@@ -1144,6 +1141,31 @@ bool LLXUIParser::writeF64Value(Parser& parser, const void* val_ptr, name_stack_
return false;
}
+bool LLXUIParser::readVector3Value(Parser& parser, void* val_ptr)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLVector3* vecp = (LLVector3*)val_ptr;
+ if(self.mCurReadNode->getFloatValue(3, vecp->mV) >= 3)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool LLXUIParser::writeVector3Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
+{
+ LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+ LLXMLNodePtr node = self.getNode(stack);
+ if (node.notNull())
+ {
+ LLVector3 vector = *((LLVector3*)val_ptr);
+ node->setFloatValue(3, vector.mV);
+ return true;
+ }
+ return false;
+}
+
bool LLXUIParser::readColor4Value(Parser& parser, void* val_ptr)
{
LLXUIParser& self = static_cast<LLXUIParser&>(parser);
diff --git a/indra/llxuixml/llxuiparser.h b/indra/llxuixml/llxuiparser.h
index d7cd256967..e48663e5cc 100644
--- a/indra/llxuixml/llxuiparser.h
+++ b/indra/llxuixml/llxuiparser.h
@@ -127,6 +127,7 @@ private:
static bool readS32Value(Parser& parser, void* val_ptr);
static bool readF32Value(Parser& parser, void* val_ptr);
static bool readF64Value(Parser& parser, void* val_ptr);
+ static bool readVector3Value(Parser& parser, void* val_ptr);
static bool readColor4Value(Parser& parser, void* val_ptr);
static bool readUIColorValue(Parser& parser, void* val_ptr);
static bool readUUIDValue(Parser& parser, void* val_ptr);
@@ -144,6 +145,7 @@ private:
static bool writeS32Value(Parser& parser, const void* val_ptr, name_stack_t&);
static bool writeF32Value(Parser& parser, const void* val_ptr, name_stack_t&);
static bool writeF64Value(Parser& parser, const void* val_ptr, name_stack_t&);
+ static bool writeVector3Value(Parser& parser, const void* val_ptr, name_stack_t&);
static bool writeColor4Value(Parser& parser, const void* val_ptr, name_stack_t&);
static bool writeUIColorValue(Parser& parser, const void* val_ptr, name_stack_t&);
static bool writeUUIDValue(Parser& parser, const void* val_ptr, name_stack_t&);
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 3c9bde34b7..b780a27ce2 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -244,6 +244,7 @@ set(viewer_SOURCE_FILES
llfloateruipreview.cpp
llfloaterurlentry.cpp
llfloatervoiceeffect.cpp
+ llfloatervoicevolume.cpp
llfloaterwebcontent.cpp
llfloaterwebprofile.cpp
llfloaterwhitelistentry.cpp
@@ -800,6 +801,7 @@ set(viewer_HEADER_FILES
llfloateruipreview.h
llfloaterurlentry.h
llfloatervoiceeffect.h
+ llfloatervoicevolume.h
llfloaterwebcontent.h
llfloaterwebprofile.h
llfloaterwhitelistentry.h
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 9a7cdcfa21..ac14ec2cc0 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -809,6 +809,26 @@ void LLAvatarActions::toggleBlock(const LLUUID& id)
}
// static
+void LLAvatarActions::toggleMuteVoice(const LLUUID& id)
+{
+ std::string name;
+ gCacheName->getFullName(id, name); // needed for mute
+
+ LLMuteList* mute_list = LLMuteList::getInstance();
+ bool is_muted = mute_list->isMuted(id, LLMute::flagVoiceChat);
+
+ LLMute mute(id, name, LLMute::AGENT);
+ if (!is_muted)
+ {
+ mute_list->add(mute, LLMute::flagVoiceChat);
+ }
+ else
+ {
+ mute_list->remove(mute, LLMute::flagVoiceChat);
+ }
+}
+
+// static
bool LLAvatarActions::canOfferTeleport(const LLUUID& id)
{
// First use LLAvatarTracker::isBuddy()
@@ -1023,6 +1043,12 @@ bool LLAvatarActions::isBlocked(const LLUUID& id)
}
// static
+bool LLAvatarActions::isVoiceMuted(const LLUUID& id)
+{
+ return LLMuteList::getInstance()->isMuted(id, LLMute::flagVoiceChat);
+}
+
+// static
bool LLAvatarActions::canBlock(const LLUUID& id)
{
std::string full_name;
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 748b7cb3d1..e5dad74fc8 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -124,6 +124,11 @@ public:
static void toggleBlock(const LLUUID& id);
/**
+ * Block/unblock the avatar voice.
+ */
+ static void toggleMuteVoice(const LLUUID& id);
+
+ /**
* Return true if avatar with "id" is a friend
*/
static bool isFriend(const LLUUID& id);
@@ -134,6 +139,11 @@ public:
static bool isBlocked(const LLUUID& id);
/**
+ * @return true if the avatar voice is blocked
+ */
+ static bool isVoiceMuted(const LLUUID& id);
+
+ /**
* @return true if you can block the avatar
*/
static bool canBlock(const LLUUID& id);
diff --git a/indra/newview/llbrowsernotification.cpp b/indra/newview/llbrowsernotification.cpp
index 6e77d1e336..9e608d2c8b 100644
--- a/indra/newview/llbrowsernotification.cpp
+++ b/indra/newview/llbrowsernotification.cpp
@@ -35,11 +35,8 @@
using namespace LLNotificationsUI;
-bool LLBrowserNotification::processNotification(const LLSD& notify)
+bool LLBrowserNotification::processNotification(const LLNotificationPtr& notification)
{
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
- if (!notification) return false;
-
LLUUID media_id = notification->getPayload()["media_id"].asUUID();
LLMediaCtrl* media_instance = LLMediaCtrl::getInstance(media_id);
if (media_instance)
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index f530d10ddc..5bdfb5adbc 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -143,7 +143,8 @@ public:
{
LLMuteList::getInstance()->add(LLMute(getAvatarId(), mFrom, LLMute::OBJECT));
- LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD().with("blocked_to_select", getAvatarId()));
+ LLFloaterSidePanelContainer::showPanel("people", "panel_people",
+ LLSD().with("people_panel_tab_name", "blocked_panel").with("blocked_to_select", getAvatarId()));
}
}
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index a661808d1f..17181edffc 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -335,30 +335,15 @@ void LLIMWellChiclet::messageCountChanged(const LLSD& session_data)
/* LLNotificationChiclet implementation */
/************************************************************************/
LLNotificationChiclet::LLNotificationChiclet(const Params& p)
-: LLSysWellChiclet(p)
-, mUreadSystemNotifications(0)
+: LLSysWellChiclet(p),
+ mUreadSystemNotifications(0)
{
- // connect counter handlers to the signals
- connectCounterUpdatersToSignal("notify");
- connectCounterUpdatersToSignal("groupnotify");
- connectCounterUpdatersToSignal("offer");
-
+ mNotificationChannel.reset(new ChicletNotificationChannel(this));
// ensure that notification well window exists, to synchronously
// handle toast add/delete events.
LLNotificationWellWindow::getInstance()->setSysWellChiclet(this);
}
-void LLNotificationChiclet::connectCounterUpdatersToSignal(const std::string& notification_type)
-{
- LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance();
- LLNotificationsUI::LLEventHandler* n_handler = manager->getHandlerForNotification(notification_type);
- if(n_handler)
- {
- n_handler->setNewNotificationCallback(boost::bind(&LLNotificationChiclet::incUreadSystemNotifications, this));
- n_handler->setDelNotification(boost::bind(&LLNotificationChiclet::decUreadSystemNotifications, this));
- }
-}
-
void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data)
{
std::string action = user_data.asString();
@@ -407,6 +392,18 @@ void LLNotificationChiclet::setCounter(S32 counter)
updateWidget(getCounter() == 0);
}
+
+bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNotificationPtr notification )
+{
+ if( !(notification->canLogToIM() && notification->hasFormElements())
+ && (!notification->getPayload().has("give_inventory_notification")
+ || notification->getPayload()["give_inventory_notification"]))
+ {
+ return true;
+ }
+ return false;
+}
+
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index 19683492c2..3973b6547a 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -34,6 +34,7 @@
#include "lloutputmonitorctrl.h"
#include "llgroupmgr.h"
#include "llimview.h"
+#include "llnotifications.h"
class LLMenuGL;
class LLIMFloater;
@@ -911,11 +912,35 @@ protected:
class LLNotificationChiclet : public LLSysWellChiclet
{
+ LOG_CLASS(LLNotificationChiclet);
+
friend class LLUICtrlFactory;
public:
struct Params : public LLInitParam::Block<Params, LLSysWellChiclet::Params>{};
protected:
+ struct ChicletNotificationChannel : public LLNotificationChannel
+ {
+ ChicletNotificationChannel(LLNotificationChiclet* chiclet)
+ : LLNotificationChannel(LLNotificationChannel::Params().filter(filterNotification).name(chiclet->getSessionId().asString())),
+ mChiclet(chiclet)
+ {
+ // connect counter handlers to the signals
+ connectToChannel("Group Notifications");
+ connectToChannel("Offer");
+ connectToChannel("Notifications");
+ }
+
+ static bool filterNotification(LLNotificationPtr notify);
+ // connect counter updaters to the corresponding signals
+ /*virtual*/ void onAdd(LLNotificationPtr p) { mChiclet->setCounter(++mChiclet->mUreadSystemNotifications); }
+ /*virtual*/ void onDelete(LLNotificationPtr p) { mChiclet->setCounter(--mChiclet->mUreadSystemNotifications); }
+
+ LLNotificationChiclet* const mChiclet;
+ };
+
+ boost::scoped_ptr<ChicletNotificationChannel> mNotificationChannel;
+
LLNotificationChiclet(const Params& p);
/**
@@ -933,12 +958,6 @@ protected:
*/
/*virtual*/ void createMenu();
- // connect counter updaters to the corresponding signals
- void connectCounterUpdatersToSignal(const std::string& notification_type);
-
- // methods for updating a number of unread System notifications
- void incUreadSystemNotifications() { setCounter(++mUreadSystemNotifications); }
- void decUreadSystemNotifications() { setCounter(--mUreadSystemNotifications); }
/*virtual*/ void setCounter(S32 counter);
S32 mUreadSystemNotifications;
};
diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp
index 2681d4b34d..4f35c325a8 100644
--- a/indra/newview/llfloaternotificationsconsole.cpp
+++ b/indra/newview/llfloaternotificationsconsole.cpp
@@ -44,21 +44,16 @@ public:
BOOL postBuild();
private:
- bool update(const LLSD& payload, bool passed_filter);
+ bool update(const LLSD& payload);
static void toggleClick(void* user_data);
static void onClickNotification(void* user_data);
- static void onClickNotificationReject(void* user_data);
LLNotificationChannelPtr mChannelPtr;
- LLNotificationChannelPtr mChannelRejectsPtr;
};
LLNotificationChannelPanel::LLNotificationChannelPanel(const LLNotificationChannelPanel::Params& p)
: LLLayoutPanel(p)
{
mChannelPtr = LLNotifications::instance().getChannel(p.name);
- mChannelRejectsPtr = LLNotificationChannelPtr(
- LLNotificationChannel::buildChannel(p.name() + "rejects", mChannelPtr->getParentChannelName(),
- !boost::bind(mChannelPtr->getFilter(), _1)));
buildFromFile( "panel_notifications_channel.xml");
}
@@ -68,15 +63,11 @@ BOOL LLNotificationChannelPanel::postBuild()
header_button->setLabel(mChannelPtr->getName());
header_button->setClickedCallback(toggleClick, this);
- mChannelPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, true));
- mChannelRejectsPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, false));
+ mChannelPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1));
LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("notifications_list");
scroll->setDoubleClickCallback(onClickNotification, this);
scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0));
- scroll = getChild<LLScrollListCtrl>("notification_rejects_list");
- scroll->setDoubleClickCallback(onClickNotificationReject, this);
- scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0));
return TRUE;
}
@@ -97,8 +88,6 @@ void LLNotificationChannelPanel::toggleClick(void *user_data)
// turn off tab stop for collapsed panel
self->getChild<LLScrollListCtrl>("notifications_list")->setTabStop(!header_button->getToggleState());
self->getChild<LLScrollListCtrl>("notifications_list")->setVisible(!header_button->getToggleState());
- self->getChild<LLScrollListCtrl>("notification_rejects_list")->setTabStop(!header_button->getToggleState());
- self->getChild<LLScrollListCtrl>("notification_rejects_list")->setVisible(!header_button->getToggleState());
}
/*static*/
@@ -118,24 +107,7 @@ void LLNotificationChannelPanel::onClickNotification(void* user_data)
}
}
-/*static*/
-void LLNotificationChannelPanel::onClickNotificationReject(void* user_data)
-{
- LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
- if (!self) return;
- LLScrollListItem* firstselected = self->getChild<LLScrollListCtrl>("notification_rejects_list")->getFirstSelected();
- llassert(firstselected);
- if (firstselected)
- {
- void* data = firstselected->getUserdata();
- if (data)
- {
- gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE);
- }
- }
-}
-
-bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter)
+bool LLNotificationChannelPanel::update(const LLSD& payload)
{
LLNotificationPtr notification = LLNotifications::instance().find(payload["id"].asUUID());
if (notification)
@@ -151,9 +123,7 @@ bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter)
row["columns"][2]["column"] = "date";
row["columns"][2]["type"] = "date";
- LLScrollListItem* sli = passed_filter ?
- getChild<LLScrollListCtrl>("notifications_list")->addElement(row) :
- getChild<LLScrollListCtrl>("notification_rejects_list")->addElement(row);
+ LLScrollListItem* sli = getChild<LLScrollListCtrl>("notifications_list")->addElement(row);
sli->setUserdata(&(*notification));
}
diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index 540f977305..c55970ad69 100644
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -44,14 +44,12 @@
#include "llviewernetwork.h"
#include "llwindowshade.h"
-#define USE_WINDOWSHADE_DIALOGS 0
-
///----------------------------------------------------------------------------
/// LLOutboxNotification class
///----------------------------------------------------------------------------
-bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLSD& notify)
+bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLNotificationPtr& notify)
{
LLFloaterOutbox* outbox_floater = LLFloaterReg::getTypedInstance<LLFloaterOutbox>("outbox");
@@ -60,6 +58,14 @@ bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLSD& no
return false;
}
+void LLNotificationsUI::LLOutboxNotification::onDelete(LLNotificationPtr p)
+{
+ LLNotificationsUI::LLSysHandler * sys_handler = dynamic_cast<LLNotificationsUI::LLSysHandler*>(LLNotifications::instance().getChannel("AlertModal").get());
+ if (sys_handler)
+ {
+ sys_handler->onDelete(p);
+ }
+}
///----------------------------------------------------------------------------
/// LLOutboxAddedObserver helper class
@@ -516,52 +522,11 @@ void LLFloaterOutbox::initializationReportError(U32 status, const LLSD& content)
updateView();
}
-void LLFloaterOutbox::showNotification(const LLSD& notify)
+void LLFloaterOutbox::showNotification(const LLNotificationPtr& notification)
{
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
- if (!notification)
- {
- llerrs << "Unable to find outbox notification!" << notify.asString() << llendl;
-
- return;
- }
-
-#if USE_WINDOWSHADE_DIALOGS
-
- if (mWindowShade)
- {
- delete mWindowShade;
- }
-
- LLRect floater_rect = getLocalRect();
- floater_rect.mTop -= getHeaderHeight();
- floater_rect.stretch(-5, 0);
-
- LLWindowShade::Params params;
- params.name = "notification_shade";
- params.rect = floater_rect;
- params.follows.flags = FOLLOWS_ALL;
- params.modal = true;
- params.can_close = false;
- params.shade_color = LLColor4::white % 0.25f;
- params.text_color = LLColor4::white;
-
- mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params);
-
- addChild(mWindowShade);
- mWindowShade->show(notification);
-
-#else
-
- LLNotificationsUI::LLEventHandler * handler =
- LLNotificationsUI::LLNotificationManager::instance().getHandlerForNotification("alertmodal");
-
- LLNotificationsUI::LLSysHandler * sys_handler = dynamic_cast<LLNotificationsUI::LLSysHandler *>(handler);
+ LLNotificationsUI::LLSysHandler * sys_handler = dynamic_cast<LLNotificationsUI::LLSysHandler*>(LLNotifications::instance().getChannel("AlertModal").get());
llassert(sys_handler);
- sys_handler->processNotification(notify);
-
-#endif
+ sys_handler->processNotification(notification);
}
diff --git a/indra/newview/llfloateroutbox.h b/indra/newview/llfloateroutbox.h
index 18baccf1c9..a91d8c1139 100644
--- a/indra/newview/llfloateroutbox.h
+++ b/indra/newview/llfloateroutbox.h
@@ -64,7 +64,7 @@ public:
EAcceptance* accept,
std::string& tooltip_msg);
- void showNotification(const LLSD& notify);
+ void showNotification(const LLNotificationPtr& notification);
BOOL handleHover(S32 x, S32 y, MASK mask);
void onMouseLeave(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 173b0e538c..1c29323594 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1502,7 +1502,8 @@ void LLFloaterPreference::onChangeMaturity()
// but the UI for this will still be enabled
void LLFloaterPreference::onClickBlockList()
{
- LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD());
+ LLFloaterSidePanelContainer::showPanel("people", "panel_people",
+ LLSD().with("people_panel_tab_name", "blocked_panel"));
}
void LLFloaterPreference::onClickProxySettings()
diff --git a/indra/newview/llfloatersidepanelcontainer.cpp b/indra/newview/llfloatersidepanelcontainer.cpp
index 5385977d95..96b5c6b09b 100644
--- a/indra/newview/llfloatersidepanelcontainer.cpp
+++ b/indra/newview/llfloatersidepanelcontainer.cpp
@@ -61,7 +61,7 @@ LLPanel* LLFloaterSidePanelContainer::openChildPanel(const std::string& panel_na
if (!getVisible())
{
- openFloater();
+ openFloater();
}
LLPanel* panel = NULL;
@@ -69,10 +69,7 @@ LLPanel* LLFloaterSidePanelContainer::openChildPanel(const std::string& panel_na
LLSideTrayPanelContainer* container = dynamic_cast<LLSideTrayPanelContainer*>(view->getParent());
if (container)
{
- LLSD new_params = params;
- new_params[LLSideTrayPanelContainer::PARAM_SUB_PANEL_NAME] = panel_name;
- container->onOpen(new_params);
-
+ container->openPanel(panel_name, params);
panel = container->getCurrentPanel();
}
else if ((panel = dynamic_cast<LLPanel*>(view)) != NULL)
diff --git a/indra/newview/llfloatervoicevolume.cpp b/indra/newview/llfloatervoicevolume.cpp
new file mode 100644
index 0000000000..87b388b30a
--- /dev/null
+++ b/indra/newview/llfloatervoicevolume.cpp
@@ -0,0 +1,209 @@
+/**
+ * @file llfloatervoicevolume.cpp
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatervoicevolume.h"
+
+// Linden libraries
+#include "llavatarname.h"
+#include "llavatarnamecache.h"
+#include "llfloater.h"
+#include "llfloaterreg.h"
+#include "lltextbox.h"
+
+// viewer files
+#include "llagent.h"
+#include "llavataractions.h"
+#include "llinspect.h"
+#include "lltransientfloatermgr.h"
+#include "llvoiceclient.h"
+
+class LLAvatarName;
+
+//////////////////////////////////////////////////////////////////////////////
+// LLFloaterVoiceVolume
+//////////////////////////////////////////////////////////////////////////////
+
+// Avatar Inspector, a small information window used when clicking
+// on avatar names in the 2D UI and in the ambient inspector widget for
+// the 3D world.
+class LLFloaterVoiceVolume : public LLInspect, LLTransientFloater
+{
+ friend class LLFloaterReg;
+
+public:
+ // avatar_id - Avatar ID for which to show information
+ // Inspector will be positioned relative to current mouse position
+ LLFloaterVoiceVolume(const LLSD& avatar_id);
+ virtual ~LLFloaterVoiceVolume();
+
+ /*virtual*/ BOOL postBuild(void);
+
+ // Because floater is single instance, need to re-parse data on each spawn
+ // (for example, inspector about same avatar but in different position)
+ /*virtual*/ void onOpen(const LLSD& avatar_id);
+
+ /*virtual*/ LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; }
+
+private:
+ // Set the volume slider to this user's current client-side volume setting,
+ // hiding/disabling if the user is not nearby.
+ void updateVolumeControls();
+
+ void onClickMuteVolume();
+ void onVolumeChange(const LLSD& data);
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+
+private:
+ LLUUID mAvatarID;
+ // Need avatar name information to spawn friend add request
+ LLAvatarName mAvatarName;
+};
+
+LLFloaterVoiceVolume::LLFloaterVoiceVolume(const LLSD& sd)
+: LLInspect(LLSD()) // single_instance, doesn't really need key
+, mAvatarID() // set in onOpen() *Note: we used to show partner's name but we dont anymore --angela 3rd Dec*
+, mAvatarName()
+{
+ LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::GLOBAL, this);
+ LLTransientFloater::init(this);
+}
+
+LLFloaterVoiceVolume::~LLFloaterVoiceVolume()
+{
+ LLTransientFloaterMgr::getInstance()->removeControlView(this);
+}
+
+/*virtual*/
+BOOL LLFloaterVoiceVolume::postBuild(void)
+{
+ getChild<LLUICtrl>("mute_btn")->setCommitCallback(
+ boost::bind(&LLFloaterVoiceVolume::onClickMuteVolume, this) );
+
+ getChild<LLUICtrl>("volume_slider")->setCommitCallback(
+ boost::bind(&LLFloaterVoiceVolume::onVolumeChange, this, _2));
+
+ return TRUE;
+}
+
+
+// Multiple calls to showInstance("floater_voice_volume", foo) will provide different
+// LLSD for foo, which we will catch here.
+//virtual
+void LLFloaterVoiceVolume::onOpen(const LLSD& data)
+{
+ // Start open animation
+ LLInspect::onOpen(data);
+
+ // Extract appropriate avatar id
+ mAvatarID = data["avatar_id"];
+
+ LLUI::positionViewNearMouse(this);
+
+ getChild<LLUICtrl>("avatar_name")->setValue("");
+ updateVolumeControls();
+
+ LLAvatarNameCache::get(mAvatarID,
+ boost::bind(&LLFloaterVoiceVolume::onAvatarNameCache, this, _1, _2));
+}
+
+void LLFloaterVoiceVolume::updateVolumeControls()
+{
+ bool voice_enabled = LLVoiceClient::getInstance()->getVoiceEnabled(mAvatarID);
+
+ LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn");
+ LLUICtrl* volume_slider = getChild<LLUICtrl>("volume_slider");
+
+ // Do not display volume slider and mute button if it
+ // is ourself or we are not in a voice channel together
+ if (!voice_enabled || (mAvatarID == gAgent.getID()))
+ {
+ mute_btn->setVisible(false);
+ volume_slider->setVisible(false);
+ }
+ else
+ {
+ mute_btn->setVisible(true);
+ volume_slider->setVisible(true);
+
+ // By convention, we only display and toggle voice mutes, not all mutes
+ bool is_muted = LLAvatarActions::isVoiceMuted(mAvatarID);
+ bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden");
+
+ mute_btn->setEnabled(!is_linden);
+ mute_btn->setValue(is_muted);
+
+ volume_slider->setEnabled(!is_muted);
+
+ F32 volume;
+ if (is_muted)
+ {
+ // it's clearer to display their volume as zero
+ volume = 0.f;
+ }
+ else
+ {
+ // actual volume
+ volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID);
+ }
+ volume_slider->setValue((F64)volume);
+ }
+
+}
+
+void LLFloaterVoiceVolume::onClickMuteVolume()
+{
+ LLAvatarActions::toggleMuteVoice(mAvatarID);
+ updateVolumeControls();
+}
+
+void LLFloaterVoiceVolume::onVolumeChange(const LLSD& data)
+{
+ F32 volume = (F32)data.asReal();
+ LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume);
+}
+
+void LLFloaterVoiceVolume::onAvatarNameCache(
+ const LLUUID& agent_id,
+ const LLAvatarName& av_name)
+{
+ if (agent_id != mAvatarID)
+ {
+ return;
+ }
+
+ getChild<LLUICtrl>("avatar_name")->setValue(av_name.getCompleteName());
+ mAvatarName = av_name;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// LLFloaterVoiceVolumeUtil
+//////////////////////////////////////////////////////////////////////////////
+void LLFloaterVoiceVolumeUtil::registerFloater()
+{
+ LLFloaterReg::add("floater_voice_volume", "floater_voice_volume.xml",
+ &LLFloaterReg::build<LLFloaterVoiceVolume>);
+}
diff --git a/indra/newview/llfloatervoicevolume.h b/indra/newview/llfloatervoicevolume.h
new file mode 100644
index 0000000000..8fcf7f250b
--- /dev/null
+++ b/indra/newview/llfloatervoicevolume.h
@@ -0,0 +1,35 @@
+/**
+ * @file llfloatervoicevolume.h
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERVOICEVOLUME_H
+#define LL_LLFLOATERVOICEVOLUME_H
+
+namespace LLFloaterVoiceVolumeUtil
+{
+ // Register with LLFloaterReg
+ void registerFloater();
+}
+
+#endif // LL_LLFLOATERVOICEVOLUME_H
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 86001e4146..f375443e38 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -176,6 +176,7 @@ LLFolderView::Params::Params()
show_load_status("show_load_status", true),
use_ellipses("use_ellipses", false)
{
+ folder_indentation = -4;
}
@@ -224,10 +225,7 @@ LLFolderView::LLFolderView(const Params& p)
mAutoOpenCandidate = NULL;
mAutoOpenTimer.stop();
mKeyboardSelection = FALSE;
- const LLFolderViewItem::Params& item_params =
- LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
- S32 indentation = item_params.folder_indentation();
- mIndentation = -indentation; // children start at indentation 0
+ mIndentation = p.folder_indentation;
gIdleCallbacks.addFunction(idle, this);
//clear label
@@ -235,7 +233,6 @@ LLFolderView::LLFolderView(const Params& p)
// just make sure the label ("Inventory Folder") never shows up
mLabel = LLStringUtil::null;
- //mRenamer->setWriteableBgColor(LLColor4::white);
// Escape is handled by reverting the rename, not commiting it (default behavior)
LLLineEditor::Params params;
params.name("ren");
@@ -527,7 +524,7 @@ void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
LLView::reshape(width, height, called_from_parent);
scroll_rect = mScrollContainer->getContentWindowRect();
}
- width = llmax(mMinWidth, scroll_rect.getWidth());
+ width = llmax(mMinWidth, scroll_rect.getWidth());
height = llmax(mRunningHeight, scroll_rect.getHeight());
// Restrict width within scroll container's width
@@ -1921,21 +1918,11 @@ BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
// when drop is not handled by child, it should be handled
// by the folder which is the hierarchy root.
- if (!handled)
- {
- if (getListener()->getUUID().notNull())
+ if (!handled
+ && getListener()->getUUID().notNull())
{
handled = LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
}
- else
- {
- if (!mFolders.empty())
- {
- // dispatch to last folder as a hack to support "Contents" folder in object inventory
- handled = mFolders.back()->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg);
- }
- }
- }
if (handled)
{
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index 1d018b5e6a..9a6bf05cd1 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -187,14 +187,6 @@ public:
// public rename functionality - can only start the process
void startRenamingSelectedItem( void );
- // These functions were used when there was only one folderview,
- // and relied on that concept. This functionality is now handled
- // by the listeners and the lldraganddroptool.
- //LLFolderViewItem* getMovingItem() { return mMovingItem; }
- //void setMovingItem( LLFolderViewItem* item ) { mMovingItem = item; }
- //void dragItemIntoFolder( LLFolderViewItem* moving_item, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept );
- //void dragFolderIntoFolder( LLFolderViewFolder* moving_folder, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept );
-
// LLView functionality
///*virtual*/ BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent );
/*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index afad27b4e0..c2dec4ab27 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -417,9 +417,8 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation)
const Params& p = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
S32 indentation = p.folder_indentation();
// Only indent deeper items in hierarchy
- mIndentation = (getParentFolder()
- && getParentFolder()->getParentFolder() )
- ? mParentFolder->getIndentation() + indentation
+ mIndentation = (getParentFolder())
+ ? getParentFolder()->getIndentation() + indentation
: 0;
if (mLabelWidthDirty)
{
diff --git a/indra/newview/llfollowcam.cpp b/indra/newview/llfollowcam.cpp
index b670af1782..47612fe25c 100644
--- a/indra/newview/llfollowcam.cpp
+++ b/indra/newview/llfollowcam.cpp
@@ -38,7 +38,6 @@ std::vector<LLFollowCamParams*> LLFollowCamMgr::sParamStack;
//-------------------------------------------------------
// constants
//-------------------------------------------------------
-const F32 ONE_HALF = 0.5;
const F32 FOLLOW_CAM_ZOOM_FACTOR = 0.1f;
const F32 FOLLOW_CAM_MIN_ZOOM_AMOUNT = 0.1f;
const F32 DISTANCE_EPSILON = 0.0001f;
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index 482294c8a6..3336097955 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -166,7 +166,6 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3&
}
// scale screen size of borders down
- //RN: for now, text on hud objects is never occluded
LLVector3 x_pixel_vec;
LLVector3 y_pixel_vec;
@@ -187,45 +186,29 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3&
+ (y_pixel_vec * screen_offset.mV[VY]);
- //if (mUseBubble)
+ LLVector3 bg_pos = render_position
+ + (F32)mOffsetY * y_pixel_vec
+ - (width_vec / 2.f)
+ - (height_vec);
+
+ LLVector3 v[] =
{
- LLVector3 bg_pos = render_position
- + (F32)mOffsetY * y_pixel_vec
- - (width_vec / 2.f)
- - (height_vec);
- //LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
+ bg_pos,
+ bg_pos + width_vec,
+ bg_pos + width_vec + height_vec,
+ bg_pos + height_vec,
+ };
- LLVector3 v[] =
- {
- bg_pos,
- bg_pos + width_vec,
- bg_pos + width_vec + height_vec,
- bg_pos + height_vec,
- };
+ LLVector3 dir = end-start;
+ F32 a, b, t;
- if (debug_render)
+ if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) ||
+ LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) )
+ {
+ if (t <= 1.f)
{
- gGL.begin(LLRender::LINE_STRIP);
- gGL.vertex3fv(v[0].mV);
- gGL.vertex3fv(v[1].mV);
- gGL.vertex3fv(v[2].mV);
- gGL.vertex3fv(v[3].mV);
- gGL.vertex3fv(v[0].mV);
- gGL.vertex3fv(v[2].mV);
- gGL.end();
- }
-
- LLVector3 dir = end-start;
- F32 a, b, t;
-
- if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) ||
- LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) )
- {
- if (t <= 1.f)
- {
- intersection = start + dir*t;
- return TRUE;
- }
+ intersection = start + dir*t;
+ return TRUE;
}
}
@@ -241,12 +224,6 @@ void LLHUDNameTag::render()
}
}
-void LLHUDNameTag::renderForSelect()
-{
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
- renderText(TRUE);
-}
-
void LLHUDNameTag::renderText(BOOL for_select)
{
if (!mVisible || mHidden)
@@ -299,24 +276,6 @@ void LLHUDNameTag::renderText(BOOL for_select)
LLColor4 bg_color = LLUIColorTable::instance().getColor("NameTagBackground");
bg_color.setAlpha(gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
- // maybe a no-op?
- //const S32 border_height = 16;
- //const S32 border_width = 16;
- const S32 border_height = 8;
- const S32 border_width = 8;
-
- // *TODO move this into helper function
- F32 border_scale = 1.f;
-
- if (border_height * 2 > mHeight)
- {
- border_scale = (F32)mHeight / ((F32)border_height * 2.f);
- }
- if (border_width * 2 > mWidth)
- {
- border_scale = llmin(border_scale, (F32)mWidth / ((F32)border_width * 2.f));
- }
-
// scale screen size of borders down
//RN: for now, text on hud objects is never occluded
@@ -325,152 +284,34 @@ void LLHUDNameTag::renderText(BOOL for_select)
LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
- LLVector2 border_scale_vec((F32)border_width / (F32)imagep->getTextureWidth(), (F32)border_height / (F32)imagep->getTextureHeight());
LLVector3 width_vec = mWidth * x_pixel_vec;
LLVector3 height_vec = mHeight * y_pixel_vec;
- LLVector3 scaled_border_width = (F32)llfloor(border_scale * (F32)border_width) * x_pixel_vec;
- LLVector3 scaled_border_height = (F32)llfloor(border_scale * (F32)border_height) * y_pixel_vec;
mRadius = (width_vec + height_vec).magVec() * 0.5f;
LLCoordGL screen_pos;
LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE);
- LLVector2 screen_offset;
-// if (!mUseBubble)
-// {
-// screen_offset = mPositionOffset;
-// }
-// else
-// {
- screen_offset = updateScreenPos(mPositionOffset);
-// }
+ LLVector2 screen_offset = updateScreenPos(mPositionOffset);
LLVector3 render_position = mPositionAgent
+ (x_pixel_vec * screen_offset.mV[VX])
+ (y_pixel_vec * screen_offset.mV[VY]);
-// if (mUseBubble)
+ LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
+ LLRect screen_rect;
+ screen_rect.setCenterAndSize(0, static_cast<S32>(lltrunc(-mHeight / 2 + mOffsetY)), static_cast<S32>(lltrunc(mWidth)), static_cast<S32>(lltrunc(mHeight)));
+ imagep->draw3D(render_position, x_pixel_vec, y_pixel_vec, screen_rect, bg_color);
+ if (mLabelSegments.size())
{
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
- LLUI::pushMatrix();
- {
- LLVector3 bg_pos = render_position
- + (F32)mOffsetY * y_pixel_vec
- - (width_vec / 2.f)
- - (height_vec);
- LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
-
- if (for_select)
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- S32 name = mSourceObject->mGLName;
- LLColor4U coloru((U8)(name >> 16), (U8)(name >> 8), (U8)name);
- gGL.color4ubv(coloru.mV);
- gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
- LLUI::popMatrix();
- return;
- }
- else
- {
- gGL.getTexUnit(0)->bind(imagep->getImage());
-
- gGL.color4fv(bg_color.mV);
- gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
-
- if ( mLabelSegments.size())
- {
- LLUI::pushMatrix();
- {
- gGL.color4f(text_color.mV[VX], text_color.mV[VY], text_color.mV[VZ], gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
- LLVector3 label_height = (mFontp->getLineHeight() * mLabelSegments.size() + (VERTICAL_PADDING / 3.f)) * y_pixel_vec;
- LLVector3 label_offset = height_vec - label_height;
- LLUI::translate(label_offset.mV[VX], label_offset.mV[VY], label_offset.mV[VZ]);
- gl_segmented_rect_3d_tex_top(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, label_height);
- }
- LLUI::popMatrix();
- }
- }
-
- BOOL outside_width = llabs(mPositionOffset.mV[VX]) > mWidth * 0.5f;
- BOOL outside_height = llabs(mPositionOffset.mV[VY] + (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.5f : 0.f)) > mHeight * (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.75f : 0.5f);
+ LLUIImagePtr rect_top_image = LLUI::getUIImage("Rounded_Rect_Top");
+ LLRect label_top_rect = screen_rect;
+ const S32 label_height = llround((mFontp->getLineHeight() * (F32)mLabelSegments.size() + (VERTICAL_PADDING / 3.f)));
+ label_top_rect.mBottom = label_top_rect.mTop - label_height;
+ LLColor4 label_top_color = text_color;
+ label_top_color.mV[VALPHA] = gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor;
- // draw line segments pointing to parent object
- if (!mOffscreen && (outside_width || outside_height))
- {
- LLUI::pushMatrix();
- {
- gGL.color4fv(bg_color.mV);
- LLVector3 target_pos = -1.f * (mPositionOffset.mV[VX] * x_pixel_vec + mPositionOffset.mV[VY] * y_pixel_vec);
- target_pos += (width_vec / 2.f);
- target_pos += mVertAlignment == ALIGN_VERT_CENTER ? (height_vec * 0.5f) : LLVector3::zero;
- target_pos -= 3.f * x_pixel_vec;
- target_pos -= 6.f * y_pixel_vec;
- LLUI::translate(target_pos.mV[VX], target_pos.mV[VY], target_pos.mV[VZ]);
- gl_segmented_rect_3d_tex(border_scale_vec, 3.f * x_pixel_vec, 3.f * y_pixel_vec, 6.f * x_pixel_vec, 6.f * y_pixel_vec);
- }
- LLUI::popMatrix();
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLDepthTest gls_depth(mZCompare ? GL_TRUE : GL_FALSE, GL_FALSE);
-
- LLVector3 box_center_offset;
- box_center_offset = (width_vec * 0.5f) + (height_vec * 0.5f);
- LLUI::translate(box_center_offset.mV[VX], box_center_offset.mV[VY], box_center_offset.mV[VZ]);
- gGL.color4fv(bg_color.mV);
- LLUI::setLineWidth(2.0);
- gGL.begin(LLRender::LINES);
- {
- if (outside_width)
- {
- LLVector3 vert;
- // draw line in x then y
- if (mPositionOffset.mV[VX] < 0.f)
- {
- // start at right edge
- vert = width_vec * 0.5f;
- gGL.vertex3fv(vert.mV);
- }
- else
- {
- // start at left edge
- vert = width_vec * -0.5f;
- gGL.vertex3fv(vert.mV);
- }
- vert = -mPositionOffset.mV[VX] * x_pixel_vec;
- gGL.vertex3fv(vert.mV);
- gGL.vertex3fv(vert.mV);
- vert -= mPositionOffset.mV[VY] * y_pixel_vec;
- vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero);
- gGL.vertex3fv(vert.mV);
- }
- else
- {
- LLVector3 vert;
- // draw line in y then x
- if (mPositionOffset.mV[VY] < 0.f)
- {
- // start at top edge
- vert = (height_vec * 0.5f) - (mPositionOffset.mV[VX] * x_pixel_vec);
- gGL.vertex3fv(vert.mV);
- }
- else
- {
- // start at bottom edge
- vert = (height_vec * -0.5f) - (mPositionOffset.mV[VX] * x_pixel_vec);
- gGL.vertex3fv(vert.mV);
- }
- vert = -mPositionOffset.mV[VY] * y_pixel_vec - mPositionOffset.mV[VX] * x_pixel_vec;
- vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero);
- gGL.vertex3fv(vert.mV);
- }
- }
- gGL.end();
- LLUI::setLineWidth(1.0);
-
- }
- }
- LLUI::popMatrix();
+ rect_top_image->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color);
}
F32 y_offset = (F32)mOffsetY;
@@ -874,29 +715,26 @@ void LLHUDNameTag::updateAll()
for (r_it = sVisibleTextObjects.rbegin(); r_it != sVisibleTextObjects.rend(); ++r_it)
{
LLHUDNameTag* textp = (*r_it);
-// if (textp->mUseBubble)
-// {
- if (current_screen_area / screen_area > LOD_2_SCREEN_COVERAGE)
- {
- textp->setLOD(3);
- }
- else if (current_screen_area / screen_area > LOD_1_SCREEN_COVERAGE)
- {
- textp->setLOD(2);
- }
- else if (current_screen_area / screen_area > LOD_0_SCREEN_COVERAGE)
- {
- textp->setLOD(1);
- }
- else
- {
- textp->setLOD(0);
- }
- textp->updateSize();
- // find on-screen position and initialize collision rectangle
- textp->mTargetPositionOffset = textp->updateScreenPos(LLVector2::zero);
- current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight());
-// }
+ if (current_screen_area / screen_area > LOD_2_SCREEN_COVERAGE)
+ {
+ textp->setLOD(3);
+ }
+ else if (current_screen_area / screen_area > LOD_1_SCREEN_COVERAGE)
+ {
+ textp->setLOD(2);
+ }
+ else if (current_screen_area / screen_area > LOD_0_SCREEN_COVERAGE)
+ {
+ textp->setLOD(1);
+ }
+ else
+ {
+ textp->setLOD(0);
+ }
+ textp->updateSize();
+ // find on-screen position and initialize collision rectangle
+ textp->mTargetPositionOffset = textp->updateScreenPos(LLVector2::zero);
+ current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight());
}
LLStat* camera_vel_stat = LLViewerCamera::getInstance()->getVelocityStat();
@@ -914,20 +752,12 @@ void LLHUDNameTag::updateAll()
{
LLHUDNameTag* src_textp = (*src_it);
-// if (!src_textp->mUseBubble)
-// {
-// continue;
-// }
VisibleTextObjectIterator dst_it = src_it;
++dst_it;
for (; dst_it != sVisibleTextObjects.end(); ++dst_it)
{
LLHUDNameTag* dst_textp = (*dst_it);
-// if (!dst_textp->mUseBubble)
-// {
-// continue;
-// }
if (src_textp->mSoftScreenRect.overlaps(dst_textp->mSoftScreenRect))
{
LLRectf intersect_rect = src_textp->mSoftScreenRect;
@@ -976,10 +806,6 @@ void LLHUDNameTag::updateAll()
VisibleTextObjectIterator this_object_it;
for (this_object_it = sVisibleTextObjects.begin(); this_object_it != sVisibleTextObjects.end(); ++this_object_it)
{
-// if (!(*this_object_it)->mUseBubble)
-// {
-// continue;
-// }
(*this_object_it)->mPositionOffset = lerp((*this_object_it)->mPositionOffset, (*this_object_it)->mTargetPositionOffset, LLCriticalDamp::getInterpolant(POSITION_DAMPING_TC));
}
}
@@ -1037,10 +863,6 @@ void LLHUDNameTag::addPickable(std::set<LLViewerObject*> &pick_list)
VisibleTextObjectIterator text_it;
for (text_it = sVisibleTextObjects.begin(); text_it != sVisibleTextObjects.end(); ++text_it)
{
-// if (!(*text_it)->mUseBubble)
-// {
-// continue;
-// }
pick_list.insert((*text_it)->mSourceObject);
}
}
diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h
index 3325c22def..72647d5b26 100644
--- a/indra/newview/llhudnametag.h
+++ b/indra/newview/llhudnametag.h
@@ -118,7 +118,6 @@ public:
/*virtual*/ void markDead();
friend class LLHUDObject;
/*virtual*/ F32 getDistance() const { return mLastDistance; }
- //void setUseBubble(BOOL use_bubble) { mUseBubble = use_bubble; }
S32 getLOD() { return mLOD; }
BOOL getVisible() { return mVisible; }
BOOL getHidden() const { return mHidden; }
@@ -136,7 +135,6 @@ protected:
LLHUDNameTag(const U8 type);
/*virtual*/ void render();
- /*virtual*/ void renderForSelect();
void renderText(BOOL for_select);
static void updateAll();
void setLOD(S32 lod);
diff --git a/indra/newview/llhudobject.cpp b/indra/newview/llhudobject.cpp
index 95d57d08d8..0960846510 100644
--- a/indra/newview/llhudobject.cpp
+++ b/indra/newview/llhudobject.cpp
@@ -232,9 +232,11 @@ LLHUDEffect *LLHUDObject::addHUDEffect(const U8 type)
case LL_HUD_EFFECT_LOOKAT:
hud_objectp = new LLHUDEffectLookAt(type);
break;
+#ifdef XXX_STINSON_CHUI_REWORK
case LL_HUD_EFFECT_VOICE_VISUALIZER:
hud_objectp = new LLVoiceVisualizer(type);
break;
+#endif // XXX_STINSON_CHUI_REWORK
case LL_HUD_EFFECT_POINTAT:
hud_objectp = new LLHUDEffectPointAt(type);
break;
diff --git a/indra/newview/llhudobject.h b/indra/newview/llhudobject.h
index 2f7a98c86c..21cf5fe17c 100644
--- a/indra/newview/llhudobject.h
+++ b/indra/newview/llhudobject.h
@@ -94,7 +94,9 @@ public:
LL_HUD_EFFECT_EDIT,
LL_HUD_EFFECT_LOOKAT,
LL_HUD_EFFECT_POINTAT,
+#ifdef XXX_STINSON_CHUI_REWORK
LL_HUD_EFFECT_VOICE_VISUALIZER, // Ventrella
+#endif // XXX_STINSON_CHUI_REWORK
LL_HUD_NAME_TAG,
LL_HUD_EFFECT_BLOB
};
diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp
index 07d73c8c66..c7034aea3a 100644
--- a/indra/newview/llimhandler.cpp
+++ b/indra/newview/llimhandler.cpp
@@ -37,10 +37,9 @@
using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
-LLIMHandler::LLIMHandler(e_notification_type type, const LLSD& id)
+LLIMHandler::LLIMHandler()
+: LLSysHandler("IM Notifications", "notifytoast")
{
- mType = type;
-
// Getting a Channel for our notifications
mChannel = LLChannelManager::getInstance()->createNotificationChannel()->getHandle();
}
@@ -59,26 +58,19 @@ void LLIMHandler::initChannel()
}
//--------------------------------------------------------------------------
-bool LLIMHandler::processNotification(const LLSD& notify)
+bool LLIMHandler::processNotification(const LLNotificationPtr& notification)
{
if(mChannel.isDead())
{
return false;
}
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
- if(!notification)
- return false;
-
// arrange a channel on a screen
if(!mChannel.get()->getVisible())
{
initChannel();
}
- if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
- {
LLSD substitutions = notification->getSubstitutions();
// According to comments in LLIMMgr::addMessage(), if we get message
@@ -103,28 +95,12 @@ bool LLIMHandler::processNotification(const LLSD& notify)
p.notification = notification;
p.panel = im_box;
p.can_be_stored = false;
- p.on_delete_toast = boost::bind(&LLIMHandler::onDeleteToast, this, _1);
LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
if(channel)
channel->addToast(p);
-
- // send a signal to the counter manager;
- mNewNotificationSignal();
- }
- else if (notify["sigtype"].asString() == "delete")
- {
- mChannel.get()->killToastByNotificationID(notification->getID());
}
return false;
}
-//--------------------------------------------------------------------------
-void LLIMHandler::onDeleteToast(LLToast* toast)
-{
- // send a signal to the counter manager
- mDelNotificationSignal();
-}
-
-//--------------------------------------------------------------------------
diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index 17d0b0ffbb..8a15cd279f 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -28,38 +28,21 @@
#include "llinspectavatar.h"
// viewer files
-#include "llagent.h"
-#include "llagentdata.h"
-#include "llavataractions.h"
+#include "llavatariconctrl.h"
#include "llavatarnamecache.h"
#include "llavatarpropertiesprocessor.h"
-#include "llcallingcard.h"
#include "lldateutil.h"
-#include "llfloaterreporter.h"
-#include "llfloaterworldmap.h"
-#include "llimview.h"
#include "llinspect.h"
-#include "llmutelist.h"
-#include "llpanelblockedlist.h"
+#include "llslurl.h"
#include "llstartup.h"
-#include "llspeakers.h"
-#include "llviewermenu.h"
-#include "llvoiceclient.h"
-#include "llviewerobjectlist.h"
#include "lltransientfloatermgr.h"
-#include "llnotificationsutil.h"
// Linden libraries
#include "llfloater.h"
#include "llfloaterreg.h"
-#include "llmenubutton.h"
#include "lltextbox.h"
-#include "lltoggleablemenu.h"
#include "lltooltip.h" // positionViewNearMouse()
#include "lltrans.h"
-#include "lluictrl.h"
-
-#include "llavatariconctrl.h"
class LLFetchAvatarData;
@@ -81,22 +64,13 @@ public:
LLInspectAvatar(const LLSD& avatar_id);
virtual ~LLInspectAvatar();
- /*virtual*/ BOOL postBuild(void);
-
// Because floater is single instance, need to re-parse data on each spawn
// (for example, inspector about same avatar but in different position)
/*virtual*/ void onOpen(const LLSD& avatar_id);
- // When closing they should close their gear menu
- /*virtual*/ void onClose(bool app_quitting);
-
// Update view based on information from avatar properties processor
void processAvatarData(LLAvatarData* data);
- // override the inspector mouse leave so timer is only paused if
- // gear menu is not open
- /* virtual */ void onMouseLeave(S32 x, S32 y, MASK mask);
-
virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; }
private:
@@ -104,47 +78,6 @@ private:
// Used on construction and if avatar id changes.
void requestUpdate();
- // Set the volume slider to this user's current client-side volume setting,
- // hiding/disabling if the user is not nearby.
- void updateVolumeSlider();
-
- // Shows/hides moderator panel depending on voice state
- void updateModeratorPanel();
-
- // Moderator ability to enable/disable voice chat for avatar
- void toggleSelectedVoice(bool enabled);
-
- // Button callbacks
- void onClickAddFriend();
- void onClickViewProfile();
- void onClickIM();
- void onClickCall();
- void onClickTeleport();
- void onClickInviteToGroup();
- void onClickPay();
- void onClickShare();
- void onToggleMute();
- void onClickReport();
- void onClickFreeze();
- void onClickEject();
- void onClickKick();
- void onClickCSR();
- void onClickZoomIn();
- void onClickFindOnMap();
- bool onVisibleFindOnMap();
- bool onVisibleEject();
- bool onVisibleFreeze();
- bool onVisibleZoomIn();
- void onClickMuteVolume();
- void onVolumeChange(const LLSD& data);
- bool enableMute();
- bool enableUnmute();
- bool enableTeleportOffer();
- bool godModeEnabled();
-
- // Is used to determine if "Add friend" option should be enabled in gear menu
- bool isNotFriend();
-
void onAvatarNameCache(const LLUUID& agent_id,
const LLAvatarName& av_name);
@@ -209,39 +142,8 @@ LLInspectAvatar::LLInspectAvatar(const LLSD& sd)
mAvatarName(),
mPropertiesRequest(NULL)
{
- mCommitCallbackRegistrar.add("InspectAvatar.ViewProfile", boost::bind(&LLInspectAvatar::onClickViewProfile, this));
- mCommitCallbackRegistrar.add("InspectAvatar.AddFriend", boost::bind(&LLInspectAvatar::onClickAddFriend, this));
- mCommitCallbackRegistrar.add("InspectAvatar.IM",
- boost::bind(&LLInspectAvatar::onClickIM, this));
- mCommitCallbackRegistrar.add("InspectAvatar.Call", boost::bind(&LLInspectAvatar::onClickCall, this));
- mCommitCallbackRegistrar.add("InspectAvatar.Teleport", boost::bind(&LLInspectAvatar::onClickTeleport, this));
- mCommitCallbackRegistrar.add("InspectAvatar.InviteToGroup", boost::bind(&LLInspectAvatar::onClickInviteToGroup, this));
- mCommitCallbackRegistrar.add("InspectAvatar.Pay", boost::bind(&LLInspectAvatar::onClickPay, this));
- mCommitCallbackRegistrar.add("InspectAvatar.Share", boost::bind(&LLInspectAvatar::onClickShare, this));
- mCommitCallbackRegistrar.add("InspectAvatar.ToggleMute", boost::bind(&LLInspectAvatar::onToggleMute, this));
- mCommitCallbackRegistrar.add("InspectAvatar.Freeze", boost::bind(&LLInspectAvatar::onClickFreeze, this));
- mCommitCallbackRegistrar.add("InspectAvatar.Eject", boost::bind(&LLInspectAvatar::onClickEject, this));
- mCommitCallbackRegistrar.add("InspectAvatar.Kick", boost::bind(&LLInspectAvatar::onClickKick, this));
- mCommitCallbackRegistrar.add("InspectAvatar.CSR", boost::bind(&LLInspectAvatar::onClickCSR, this));
- mCommitCallbackRegistrar.add("InspectAvatar.Report", boost::bind(&LLInspectAvatar::onClickReport, this));
- mCommitCallbackRegistrar.add("InspectAvatar.FindOnMap", boost::bind(&LLInspectAvatar::onClickFindOnMap, this));
- mCommitCallbackRegistrar.add("InspectAvatar.ZoomIn", boost::bind(&LLInspectAvatar::onClickZoomIn, this));
- mCommitCallbackRegistrar.add("InspectAvatar.DisableVoice", boost::bind(&LLInspectAvatar::toggleSelectedVoice, this, false));
- mCommitCallbackRegistrar.add("InspectAvatar.EnableVoice", boost::bind(&LLInspectAvatar::toggleSelectedVoice, this, true));
-
- mEnableCallbackRegistrar.add("InspectAvatar.EnableGod", boost::bind(&LLInspectAvatar::godModeEnabled, this));
- mEnableCallbackRegistrar.add("InspectAvatar.VisibleFindOnMap", boost::bind(&LLInspectAvatar::onVisibleFindOnMap, this));
- mEnableCallbackRegistrar.add("InspectAvatar.VisibleEject", boost::bind(&LLInspectAvatar::onVisibleEject, this));
- mEnableCallbackRegistrar.add("InspectAvatar.VisibleFreeze", boost::bind(&LLInspectAvatar::onVisibleFreeze, this));
- mEnableCallbackRegistrar.add("InspectAvatar.VisibleZoomIn", boost::bind(&LLInspectAvatar::onVisibleZoomIn, this));
- mEnableCallbackRegistrar.add("InspectAvatar.Gear.Enable", boost::bind(&LLInspectAvatar::isNotFriend, this));
- mEnableCallbackRegistrar.add("InspectAvatar.Gear.EnableCall", boost::bind(&LLAvatarActions::canCall));
- mEnableCallbackRegistrar.add("InspectAvatar.Gear.EnableTeleportOffer", boost::bind(&LLInspectAvatar::enableTeleportOffer, this));
- mEnableCallbackRegistrar.add("InspectAvatar.EnableMute", boost::bind(&LLInspectAvatar::enableMute, this));
- mEnableCallbackRegistrar.add("InspectAvatar.EnableUnmute", boost::bind(&LLInspectAvatar::enableUnmute, this));
-
// can't make the properties request until the widgets are constructed
- // as it might return immediately, so do it in postBuild.
+ // as it might return immediately, so do it in onOpen.
LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::GLOBAL, this);
LLTransientFloater::init(this);
@@ -257,25 +159,6 @@ LLInspectAvatar::~LLInspectAvatar()
LLTransientFloaterMgr::getInstance()->removeControlView(this);
}
-/*virtual*/
-BOOL LLInspectAvatar::postBuild(void)
-{
- getChild<LLUICtrl>("add_friend_btn")->setCommitCallback(
- boost::bind(&LLInspectAvatar::onClickAddFriend, this) );
-
- getChild<LLUICtrl>("view_profile_btn")->setCommitCallback(
- boost::bind(&LLInspectAvatar::onClickViewProfile, this) );
-
- getChild<LLUICtrl>("mute_btn")->setCommitCallback(
- boost::bind(&LLInspectAvatar::onClickMuteVolume, this) );
-
- getChild<LLUICtrl>("volume_slider")->setCommitCallback(
- boost::bind(&LLInspectAvatar::onVolumeChange, this, _2));
-
- return TRUE;
-}
-
-
// Multiple calls to showInstance("inspect_avatar", foo) will provide different
// LLSD for foo, which we will catch here.
//virtual
@@ -287,11 +170,6 @@ void LLInspectAvatar::onOpen(const LLSD& data)
// Extract appropriate avatar id
mAvatarID = data["avatar_id"];
- BOOL self = mAvatarID == gAgent.getID();
-
- getChild<LLUICtrl>("gear_self_btn")->setVisible(self);
- getChild<LLUICtrl>("gear_btn")->setVisible(!self);
-
// Position the inspector relative to the mouse cursor
// Similar to how tooltips are positioned
// See LLToolTipMgr::createToolTip
@@ -304,20 +182,13 @@ void LLInspectAvatar::onOpen(const LLSD& data)
LLUI::positionViewNearMouse(this);
}
+ // Generate link to avatar profile.
+ getChild<LLUICtrl>("avatar_profile_link")->setTextArg("[LINK]", LLSLURL("agent", mAvatarID, "about").getSLURLString());
+
// can't call from constructor as widgets are not built yet
requestUpdate();
-
- updateVolumeSlider();
-
- updateModeratorPanel();
}
-// virtual
-void LLInspectAvatar::onClose(bool app_quitting)
-{
- getChild<LLMenuButton>("gear_btn")->hideMenu();
-}
-
void LLInspectAvatar::requestUpdate()
{
// Don't make network requests when spawning from the debug menu at the
@@ -344,25 +215,6 @@ void LLInspectAvatar::requestUpdate()
delete mPropertiesRequest;
mPropertiesRequest = new LLFetchAvatarData(mAvatarID, this);
- // You can't re-add someone as a friend if they are already your friend
- bool is_friend = LLAvatarTracker::instance().getBuddyInfo(mAvatarID) != NULL;
- bool is_self = (mAvatarID == gAgentID);
- if (is_self)
- {
- getChild<LLUICtrl>("add_friend_btn")->setVisible(false);
- getChild<LLUICtrl>("im_btn")->setVisible(false);
- }
- else if (is_friend)
- {
- getChild<LLUICtrl>("add_friend_btn")->setVisible(false);
- getChild<LLUICtrl>("im_btn")->setVisible(true);
- }
- else
- {
- getChild<LLUICtrl>("add_friend_btn")->setVisible(true);
- getChild<LLUICtrl>("im_btn")->setVisible(false);
- }
-
// Use an avatar_icon even though the image id will come down with the
// avatar properties because the avatar_icon code maintains a cache of icons
// and this may result in the image being visible sooner.
@@ -405,214 +257,6 @@ void LLInspectAvatar::processAvatarData(LLAvatarData* data)
mPropertiesRequest = NULL;
}
-// For the avatar inspector, we only want to unpause the fade timer
-// if neither the gear menu or self gear menu are open
-void LLInspectAvatar::onMouseLeave(S32 x, S32 y, MASK mask)
-{
- LLToggleableMenu* gear_menu = getChild<LLMenuButton>("gear_btn")->getMenu();
- LLToggleableMenu* gear_menu_self = getChild<LLMenuButton>("gear_self_btn")->getMenu();
- if ( gear_menu && gear_menu->getVisible() &&
- gear_menu_self && gear_menu_self->getVisible() )
- {
- return;
- }
-
- if(childHasVisiblePopupMenu())
- {
- return;
- }
-
- mOpenTimer.unpause();
-}
-
-void LLInspectAvatar::updateModeratorPanel()
-{
- bool enable_moderator_panel = false;
-
- if (LLVoiceChannel::getCurrentVoiceChannel() &&
- mAvatarID != gAgent.getID())
- {
- LLUUID session_id = LLVoiceChannel::getCurrentVoiceChannel()->getSessionID();
-
- if (session_id != LLUUID::null)
- {
- LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
-
- if (speaker_mgr)
- {
- LLPointer<LLSpeaker> self_speakerp = speaker_mgr->findSpeaker(gAgent.getID());
- LLPointer<LLSpeaker> selected_speakerp = speaker_mgr->findSpeaker(mAvatarID);
-
- if(speaker_mgr->isVoiceActive() && selected_speakerp &&
- selected_speakerp->isInVoiceChannel() &&
- ((self_speakerp && self_speakerp->mIsModerator) || gAgent.isGodlike()))
- {
- getChild<LLUICtrl>("enable_voice")->setVisible(selected_speakerp->mModeratorMutedVoice);
- getChild<LLUICtrl>("disable_voice")->setVisible(!selected_speakerp->mModeratorMutedVoice);
-
- enable_moderator_panel = true;
- }
- }
- }
- }
-
- if (enable_moderator_panel)
- {
- if (!getChild<LLUICtrl>("moderator_panel")->getVisible())
- {
- getChild<LLUICtrl>("moderator_panel")->setVisible(true);
- // stretch the floater so it can accommodate the moderator panel
- reshape(getRect().getWidth(), getRect().getHeight() + getChild<LLUICtrl>("moderator_panel")->getRect().getHeight());
- }
- }
- else if (getChild<LLUICtrl>("moderator_panel")->getVisible())
- {
- getChild<LLUICtrl>("moderator_panel")->setVisible(false);
- // shrink the inspector floater back to original size
- reshape(getRect().getWidth(), getRect().getHeight() - getChild<LLUICtrl>("moderator_panel")->getRect().getHeight());
- }
-}
-
-void LLInspectAvatar::toggleSelectedVoice(bool enabled)
-{
- LLUUID session_id = LLVoiceChannel::getCurrentVoiceChannel()->getSessionID();
- LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
-
- if (speaker_mgr)
- {
- if (!gAgent.getRegion())
- return;
-
- std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest");
- LLSD data;
- data["method"] = "mute update";
- data["session-id"] = session_id;
- data["params"] = LLSD::emptyMap();
- data["params"]["agent_id"] = mAvatarID;
- data["params"]["mute_info"] = LLSD::emptyMap();
- // ctrl value represents ability to type, so invert
- data["params"]["mute_info"]["voice"] = !enabled;
-
- class MuteVoiceResponder : public LLHTTPClient::Responder
- {
- public:
- MuteVoiceResponder(const LLUUID& session_id)
- {
- mSessionID = session_id;
- }
-
- virtual void error(U32 status, const std::string& reason)
- {
- llwarns << status << ": " << reason << llendl;
-
- if ( gIMMgr )
- {
- //403 == you're not a mod
- //should be disabled if you're not a moderator
- if ( 403 == status )
- {
- gIMMgr->showSessionEventError(
- "mute",
- "not_a_moderator",
- mSessionID);
- }
- else
- {
- gIMMgr->showSessionEventError(
- "mute",
- "generic",
- mSessionID);
- }
- }
- }
-
- private:
- LLUUID mSessionID;
- };
-
- LLHTTPClient::post(
- url,
- data,
- new MuteVoiceResponder(speaker_mgr->getSessionID()));
- }
-
- closeFloater();
-
-}
-
-void LLInspectAvatar::updateVolumeSlider()
-{
- bool voice_enabled = LLVoiceClient::getInstance()->getVoiceEnabled(mAvatarID);
-
- // Do not display volume slider and mute button if it
- // is ourself or we are not in a voice channel together
- if (!voice_enabled || (mAvatarID == gAgent.getID()))
- {
- getChild<LLUICtrl>("mute_btn")->setVisible(false);
- getChild<LLUICtrl>("volume_slider")->setVisible(false);
- }
-
- else
- {
- getChild<LLUICtrl>("mute_btn")->setVisible(true);
- getChild<LLUICtrl>("volume_slider")->setVisible(true);
-
- // By convention, we only display and toggle voice mutes, not all mutes
- bool is_muted = LLMuteList::getInstance()->
- isMuted(mAvatarID, LLMute::flagVoiceChat);
-
- LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn");
-
- bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden");
-
- mute_btn->setEnabled( !is_linden);
- mute_btn->setValue( is_muted );
-
- LLUICtrl* volume_slider = getChild<LLUICtrl>("volume_slider");
- volume_slider->setEnabled( !is_muted );
-
- F32 volume;
-
- if (is_muted)
- {
- // it's clearer to display their volume as zero
- volume = 0.f;
- }
- else
- {
- // actual volume
- volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID);
- }
- volume_slider->setValue( (F64)volume );
- }
-
-}
-
-void LLInspectAvatar::onClickMuteVolume()
-{
- // By convention, we only display and toggle voice mutes, not all mutes
- LLMuteList* mute_list = LLMuteList::getInstance();
- bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat);
-
- LLMute mute(mAvatarID, mAvatarName.getLegacyName(), LLMute::AGENT);
- if (!is_muted)
- {
- mute_list->add(mute, LLMute::flagVoiceChat);
- }
- else
- {
- mute_list->remove(mute, LLMute::flagVoiceChat);
- }
-
- updateVolumeSlider();
-}
-
-void LLInspectAvatar::onVolumeChange(const LLSD& data)
-{
- F32 volume = (F32)data.asReal();
- LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume);
-}
-
void LLInspectAvatar::onAvatarNameCache(
const LLUUID& agent_id,
const LLAvatarName& av_name)
@@ -640,215 +284,6 @@ void LLInspectAvatar::onAvatarNameCache(
}
}
-void LLInspectAvatar::onClickAddFriend()
-{
- LLAvatarActions::requestFriendshipDialog(mAvatarID, mAvatarName.getLegacyName());
- closeFloater();
-}
-
-void LLInspectAvatar::onClickViewProfile()
-{
- LLAvatarActions::showProfile(mAvatarID);
- closeFloater();
-}
-
-bool LLInspectAvatar::isNotFriend()
-{
- return !LLAvatarActions::isFriend(mAvatarID);
-}
-
-bool LLInspectAvatar::onVisibleFindOnMap()
-{
- return gAgent.isGodlike() || is_agent_mappable(mAvatarID);
-}
-
-bool LLInspectAvatar::onVisibleEject()
-{
- return enable_freeze_eject( LLSD(mAvatarID) );
-}
-
-bool LLInspectAvatar::onVisibleFreeze()
-{
- // either user is a god and can do long distance freeze
- // or check for target proximity and permissions
- return gAgent.isGodlike() || enable_freeze_eject(LLSD(mAvatarID));
-}
-
-bool LLInspectAvatar::onVisibleZoomIn()
-{
- return gObjectList.findObject(mAvatarID);
-}
-
-void LLInspectAvatar::onClickIM()
-{
- LLAvatarActions::startIM(mAvatarID);
- closeFloater();
-}
-
-void LLInspectAvatar::onClickCall()
-{
- LLAvatarActions::startCall(mAvatarID);
- closeFloater();
-}
-
-void LLInspectAvatar::onClickTeleport()
-{
- LLAvatarActions::offerTeleport(mAvatarID);
- closeFloater();
-}
-
-void LLInspectAvatar::onClickInviteToGroup()
-{
- LLAvatarActions::inviteToGroup(mAvatarID);
- closeFloater();
-}
-
-void LLInspectAvatar::onClickPay()
-{
- LLAvatarActions::pay(mAvatarID);
- closeFloater();
-}
-
-void LLInspectAvatar::onClickShare()
-{
- LLAvatarActions::share(mAvatarID);
- closeFloater();
-}
-
-void LLInspectAvatar::onToggleMute()
-{
- LLMute mute(mAvatarID, mAvatarName.mDisplayName, LLMute::AGENT);
-
- if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName))
- {
- LLMuteList::getInstance()->remove(mute);
- }
- else
- {
- LLMuteList::getInstance()->add(mute);
- }
-
- LLPanelBlockedList::showPanelAndSelect(mute.mID);
- closeFloater();
-}
-
-void LLInspectAvatar::onClickReport()
-{
- LLFloaterReporter::showFromAvatar(mAvatarID, mAvatarName.getCompleteName());
- closeFloater();
-}
-
-bool godlike_freeze(const LLSD& notification, const LLSD& response)
-{
- LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-
- switch (option)
- {
- case 0:
- LLAvatarActions::freeze(avatar_id);
- break;
- case 1:
- LLAvatarActions::unfreeze(avatar_id);
- break;
- default:
- break;
- }
-
- return false;
-}
-
-void LLInspectAvatar::onClickFreeze()
-{
- if (gAgent.isGodlike())
- {
- // use godlike freeze-at-a-distance, with confirmation
- LLNotificationsUtil::add("FreezeAvatar",
- LLSD(),
- LLSD().with("avatar_id", mAvatarID),
- godlike_freeze);
- }
- else
- {
- // use default "local" version of freezing that requires avatar to be in range
- handle_avatar_freeze( LLSD(mAvatarID) );
- }
- closeFloater();
-}
-
-void LLInspectAvatar::onClickEject()
-{
- handle_avatar_eject( LLSD(mAvatarID) );
- closeFloater();
-}
-
-void LLInspectAvatar::onClickKick()
-{
- LLAvatarActions::kick(mAvatarID);
- closeFloater();
-}
-
-void LLInspectAvatar::onClickCSR()
-{
- std::string name;
- gCacheName->getFullName(mAvatarID, name);
- LLAvatarActions::csr(mAvatarID, name);
- closeFloater();
-}
-
-void LLInspectAvatar::onClickZoomIn()
-{
- handle_zoom_to_object(mAvatarID);
- closeFloater();
-}
-
-void LLInspectAvatar::onClickFindOnMap()
-{
- gFloaterWorldMap->trackAvatar(mAvatarID, mAvatarName.mDisplayName);
- LLFloaterReg::showInstance("world_map");
-}
-
-
-bool LLInspectAvatar::enableMute()
-{
- bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden");
- bool is_self = mAvatarID == gAgent.getID();
-
- if (!is_linden && !is_self && !LLMuteList::getInstance()->isMuted(mAvatarID, mAvatarName.getLegacyName()))
- {
- return true;
- }
- else
- {
- return false;
- }
-}
-
-bool LLInspectAvatar::enableUnmute()
-{
- bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden");
- bool is_self = mAvatarID == gAgent.getID();
-
- if (!is_linden && !is_self && LLMuteList::getInstance()->isMuted(mAvatarID, mAvatarName.getLegacyName()))
- {
- return true;
- }
- else
- {
- return false;
- }
-}
-
-bool LLInspectAvatar::enableTeleportOffer()
-{
- return LLAvatarActions::canOfferTeleport(mAvatarID);
-}
-
-bool LLInspectAvatar::godModeEnabled()
-{
- return gAgent.isGodlike();
-}
-
//////////////////////////////////////////////////////////////////////////////
// LLInspectAvatarUtil
//////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/lllistcontextmenu.h b/indra/newview/lllistcontextmenu.h
index fabd68ee20..04d3314829 100644
--- a/indra/newview/lllistcontextmenu.h
+++ b/indra/newview/lllistcontextmenu.h
@@ -37,7 +37,7 @@ class LLContextMenu;
/**
* Context menu for single or multiple list items.
*
- * Derived classes must implement contextMenu().
+ * Derived classes must implement createMenu().
*
* Typical usage:
* <code>
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index 600fd395fb..4d9db01e0d 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -445,10 +445,8 @@ void LLNearbyChatScreenChannel::arrangeToasts()
//-----------------------------------------------------------------------------------------------
boost::scoped_ptr<LLEventPump> LLNearbyChatHandler::sChatWatcher(new LLEventStream("LLChat"));
-LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& id)
+LLNearbyChatHandler::LLNearbyChatHandler()
{
- mType = type;
-
// Getting a Channel for our notifications
LLNearbyChatScreenChannel::Params p;
p.id = LLUUID(gSavedSettings.getString("NearByChatChannelUUID"));
@@ -617,10 +615,6 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
}
}
-void LLNearbyChatHandler::onDeleteToast(LLToast* toast)
-{
-}
-
//-----------------------------------------------------------------------------------------------
// LLNearbyChatToast
diff --git a/indra/newview/llnearbychathandler.h b/indra/newview/llnearbychathandler.h
index b0e4f62d51..a5034ac1cb 100644
--- a/indra/newview/llnearbychathandler.h
+++ b/indra/newview/llnearbychathandler.h
@@ -37,14 +37,13 @@ namespace LLNotificationsUI{
class LLNearbyChatHandler : public LLChatHandler
{
public:
- LLNearbyChatHandler(e_notification_type type,const LLSD& id);
+ LLNearbyChatHandler();
virtual ~LLNearbyChatHandler();
virtual void processChat(const LLChat& chat_msg, const LLSD &args);
protected:
- virtual void onDeleteToast(LLToast* toast);
virtual void initChannel();
static boost::scoped_ptr<LLEventPump> sChatWatcher;
diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp
index 89fe7bb3c2..d13e2b629d 100644
--- a/indra/newview/llnotificationalerthandler.cpp
+++ b/indra/newview/llnotificationalerthandler.cpp
@@ -40,10 +40,10 @@
using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
-LLAlertHandler::LLAlertHandler(e_notification_type type, const LLSD& id) : mIsModal(false)
+LLAlertHandler::LLAlertHandler(const std::string& name, const std::string& notification_type, bool is_modal)
+: LLSysHandler(name, notification_type),
+ mIsModal(is_modal)
{
- mType = type;
-
LLScreenChannelBase::Params p;
p.id = LLUUID(gSavedSettings.getString("AlertChannelUUID"));
p.display_toasts_always = true;
@@ -68,27 +68,20 @@ void LLAlertHandler::initChannel()
}
//--------------------------------------------------------------------------
-bool LLAlertHandler::processNotification(const LLSD& notify)
+bool LLAlertHandler::processNotification(const LLNotificationPtr& notification)
{
if(mChannel.isDead())
{
return false;
}
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
- if(!notification)
- return false;
-
// arrange a channel on a screen
if(!mChannel.get()->getVisible())
{
initChannel();
}
- if (notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "load")
- {
- if (LLHandlerUtil::canSpawnSessionAndLogToIM(notification))
+ if (notification->canLogToIM() && notification->hasFormElements())
{
const std::string name = LLHandlerUtil::getSubstitutionName(notification);
@@ -119,28 +112,14 @@ bool LLAlertHandler::processNotification(const LLSD& notify)
LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
if(channel)
channel->addToast(p);
- }
- else if (notify["sigtype"].asString() == "change")
- {
- LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
- LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
- if(channel)
- channel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
- }
- else
- {
- LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
- if(channel)
- channel->killToastByNotificationID(notification->getID());
- }
+
return false;
-}
-
-//--------------------------------------------------------------------------
+ }
-void LLAlertHandler::onDeleteToast(LLToast* toast)
+void LLAlertHandler::onChange( LLNotificationPtr notification )
{
+ LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+ if(channel)
+ channel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
}
-
-//--------------------------------------------------------------------------
-
diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp
index ad51389241..50db4737ce 100644
--- a/indra/newview/llnotificationgrouphandler.cpp
+++ b/indra/newview/llnotificationgrouphandler.cpp
@@ -37,15 +37,13 @@
using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
-LLGroupHandler::LLGroupHandler(e_notification_type type, const LLSD& id)
+LLGroupHandler::LLGroupHandler()
+: LLSysHandler("Group Notifications", "groupnotify")
{
- mType = type;
-
// Getting a Channel for our notifications
LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
if(channel)
- {
- channel->setOnRejectToastCallback(boost::bind(&LLGroupHandler::onRejectToast, this, _1));
+ channel->addOnRejectToastCallback(boost::bind(&LLGroupHandler::onRejectToast, this, _1));
mChannel = channel->getHandle();
}
}
@@ -64,68 +62,43 @@ void LLGroupHandler::initChannel()
}
//--------------------------------------------------------------------------
-bool LLGroupHandler::processNotification(const LLSD& notify)
+bool LLGroupHandler::processNotification(const LLNotificationPtr& notification)
{
if(mChannel.isDead())
{
return false;
}
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
- if(!notification)
- return false;
-
// arrange a channel on a screen
if(!mChannel.get()->getVisible())
{
initChannel();
}
- if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
- {
- LLHandlerUtil::logGroupNoticeToIMGroup(notification);
+ LLHandlerUtil::logGroupNoticeToIMGroup(notification);
- LLPanel* notify_box = new LLToastGroupNotifyPanel(notification);
- LLToast::Params p;
- p.notif_id = notification->getID();
- p.notification = notification;
- p.panel = notify_box;
- p.on_delete_toast = boost::bind(&LLGroupHandler::onDeleteToast, this, _1);
+ LLPanel* notify_box = new LLToastGroupNotifyPanel(notification);
+ LLToast::Params p;
+ p.notif_id = notification->getID();
+ p.notification = notification;
+ p.panel = notify_box;
+ p.on_delete_toast = boost::bind(&LLGroupHandler::onDeleteToast, this, _1);
- LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
- if(channel)
- channel->addToast(p);
+ LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+ if(channel)
+ channel->addToast(p);
- // send a signal to the counter manager
- mNewNotificationSignal();
+ LLGroupActions::refresh_notices();
- LLGroupActions::refresh_notices();
- }
- else if (notify["sigtype"].asString() == "delete")
- {
- mChannel.get()->killToastByNotificationID(notification->getID());
- }
return false;
}
//--------------------------------------------------------------------------
-void LLGroupHandler::onDeleteToast(LLToast* toast)
-{
- // send a signal to the counter manager
- mDelNotificationSignal();
-
- // send a signal to a listener to let him perform some action
- // in this case listener is a SysWellWindow and it will remove a corresponding item from its list
- mNotificationIDSignal(toast->getNotificationID());
-}
-
-//--------------------------------------------------------------------------
void LLGroupHandler::onRejectToast(LLUUID& id)
{
LLNotificationPtr notification = LLNotifications::instance().find(id);
- if (notification && LLNotificationManager::getInstance()->getHandlerForNotification(notification->getType()) == this)
+ if (notification && mItems.find(notification) != mItems.end())
{
LLNotifications::instance().cancel(notification);
}
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 3569ad6447..805e29e2a4 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -30,7 +30,7 @@
#include "llwindow.h"
-//#include "llnotificationsutil.h"
+#include "llnotifications.h"
#include "llchannelmanager.h"
#include "llchat.h"
#include "llinstantmessage.h"
@@ -40,20 +40,6 @@ class LLIMFloater;
namespace LLNotificationsUI
{
-// ENotificationType enumerates all possible types of notifications that could be met
-//
-typedef enum e_notification_type
-{
- NT_NOTIFY,
- NT_NOTIFYTIP,
- NT_GROUPNOTIFY,
- NT_IMCHAT,
- NT_GROUPCHAT,
- NT_NEARBYCHAT,
- NT_ALERT,
- NT_ALERTMODAL,
- NT_OFFER
-} ENotificationType;
/**
* Handler of notification events.
@@ -81,21 +67,8 @@ class LLEventHandler
public:
virtual ~LLEventHandler() {};
- // callbacks for counters
- typedef boost::function<void (void)> notification_callback_t;
- typedef boost::signals2::signal<void (void)> notification_signal_t;
- notification_signal_t mNewNotificationSignal;
- notification_signal_t mDelNotificationSignal;
- boost::signals2::connection setNewNotificationCallback(notification_callback_t cb) { return mNewNotificationSignal.connect(cb); }
- boost::signals2::connection setDelNotification(notification_callback_t cb) { return mDelNotificationSignal.connect(cb); }
- // callback for notification/toast
- typedef boost::function<void (const LLUUID id)> notification_id_callback_t;
- typedef boost::signals2::signal<void (const LLUUID id)> notification_id_signal_t;
- notification_id_signal_t mNotificationIDSignal;
- boost::signals2::connection setNotificationIDCallback(notification_id_callback_t cb) { return mNotificationIDSignal.connect(cb); }
-
protected:
- virtual void onDeleteToast(LLToast* toast)=0;
+ virtual void onDeleteToast(LLToast* toast) {}
// arrange handler's channel on a screen
// is necessary to unbind a moment of creation of a channel and a moment of positioning of it
@@ -104,8 +77,6 @@ protected:
virtual void initChannel()=0;
LLHandle<LLScreenChannelBase> mChannel;
- e_notification_type mType;
-
};
// LLSysHandler and LLChatHandler are more specific base classes
@@ -115,13 +86,18 @@ protected:
/**
* Handler for system notifications.
*/
-class LLSysHandler : public LLEventHandler
+class LLSysHandler : public LLEventHandler, public LLNotificationChannel
{
public:
- LLSysHandler();
+ LLSysHandler(const std::string& name, const std::string& notification_type);
virtual ~LLSysHandler() {};
- virtual bool processNotification(const LLSD& notify)=0;
+ // base interface functions
+ /*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); }
+ /*virtual*/ void onLoad(LLNotificationPtr p) { processNotification(p); }
+ /*virtual*/ void onDelete(LLNotificationPtr p) { if (mChannel) mChannel->killToastByNotificationID(p->getID());}
+
+ virtual bool processNotification(const LLNotificationPtr& notify)=0;
protected :
static void init();
@@ -149,15 +125,12 @@ public:
class LLIMHandler : public LLSysHandler
{
public:
- LLIMHandler(e_notification_type type, const LLSD& id);
+ LLIMHandler();
virtual ~LLIMHandler();
- // base interface functions
- virtual bool processNotification(const LLSD& notify);
-
protected:
- virtual void onDeleteToast(LLToast* toast);
- virtual void initChannel();
+ bool processNotification(const LLNotificationPtr& p);
+ /*virtual*/ void initChannel();
};
/**
@@ -167,16 +140,16 @@ protected:
class LLTipHandler : public LLSysHandler
{
public:
- LLTipHandler(e_notification_type type, const LLSD& id);
+ LLTipHandler();
virtual ~LLTipHandler();
// base interface functions
- virtual bool processNotification(const LLSD& notify);
+ /*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
+ /*virtual*/ bool processNotification(const LLNotificationPtr& p);
protected:
- virtual void onDeleteToast(LLToast* toast);
- virtual void onRejectToast(const LLUUID& id);
- virtual void initChannel();
+ /*virtual*/ void onRejectToast(const LLUUID& id);
+ /*virtual*/ void initChannel();
};
/**
@@ -186,15 +159,16 @@ protected:
class LLScriptHandler : public LLSysHandler
{
public:
- LLScriptHandler(e_notification_type type, const LLSD& id);
+ LLScriptHandler();
virtual ~LLScriptHandler();
+ /*virtual*/ void onDelete(LLNotificationPtr p);
// base interface functions
- virtual bool processNotification(const LLSD& notify);
+ /*virtual*/ bool processNotification(const LLNotificationPtr& p);
protected:
- virtual void onDeleteToast(LLToast* toast);
- virtual void initChannel();
+ /*virtual*/ void onDeleteToast(LLToast* toast);
+ /*virtual*/ void initChannel();
// own handlers
void onRejectToast(LLUUID& id);
@@ -207,14 +181,14 @@ protected:
class LLGroupHandler : public LLSysHandler
{
public:
- LLGroupHandler(e_notification_type type, const LLSD& id);
+ LLGroupHandler();
virtual ~LLGroupHandler();
// base interface functions
- virtual bool processNotification(const LLSD& notify);
+ /*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
+ /*virtual*/ bool processNotification(const LLNotificationPtr& p);
protected:
- virtual void onDeleteToast(LLToast* toast);
virtual void initChannel();
// own handlers
@@ -227,16 +201,14 @@ protected:
class LLAlertHandler : public LLSysHandler
{
public:
- LLAlertHandler(e_notification_type type, const LLSD& id);
+ LLAlertHandler(const std::string& name, const std::string& notification_type, bool is_modal);
virtual ~LLAlertHandler();
- void setAlertMode(bool is_modal) { mIsModal = is_modal; }
-
- // base interface functions
- virtual bool processNotification(const LLSD& notify);
+ /*virtual*/ void onChange(LLNotificationPtr p);
+ /*virtual*/ void onLoad(LLNotificationPtr p) { processNotification(p); }
+ /*virtual*/ bool processNotification(const LLNotificationPtr& p);
protected:
- virtual void onDeleteToast(LLToast* toast);
virtual void initChannel();
bool mIsModal;
@@ -249,15 +221,16 @@ protected:
class LLOfferHandler : public LLSysHandler
{
public:
- LLOfferHandler(e_notification_type type, const LLSD& id);
+ LLOfferHandler();
virtual ~LLOfferHandler();
// base interface functions
- virtual bool processNotification(const LLSD& notify);
+ /*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
+ /*virtual*/ void onDelete(LLNotificationPtr notification);
+ /*virtual*/ bool processNotification(const LLNotificationPtr& p);
protected:
- virtual void onDeleteToast(LLToast* toast);
- virtual void initChannel();
+ /*virtual*/ void initChannel();
// own handlers
void onRejectToast(LLUUID& id);
@@ -266,85 +239,56 @@ protected:
/**
* Handler for UI hints.
*/
-class LLHintHandler : public LLSingleton<LLHintHandler>
+class LLHintHandler : public LLNotificationChannel
{
public:
- LLHintHandler();
- virtual ~LLHintHandler();
+ LLHintHandler() : LLNotificationChannel("Hints", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "hint"))
+ {}
+ virtual ~LLHintHandler() {}
- // base interface functions
- virtual bool processNotification(const LLSD& notify);
+ /*virtual*/ void onAdd(LLNotificationPtr p);
+ /*virtual*/ void onLoad(LLNotificationPtr p);
+ /*virtual*/ void onDelete(LLNotificationPtr p);
};
/**
* Handler for browser notifications
*/
-class LLBrowserNotification : public LLSingleton<LLBrowserNotification>
+class LLBrowserNotification : public LLNotificationChannel
{
public:
- virtual bool processNotification(const LLSD& notify);
+ LLBrowserNotification()
+ : LLNotificationChannel("Browser", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "browser"))
+ {}
+ /*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); }
+ /*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
+ bool processNotification(const LLNotificationPtr& p);
};
/**
* Handler for outbox notifications
*/
-class LLOutboxNotification : public LLSingleton<LLOutboxNotification>
+class LLOutboxNotification : public LLNotificationChannel
{
public:
- virtual bool processNotification(const LLSD& notify);
+ LLOutboxNotification()
+ : LLNotificationChannel("Outbox", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "outbox"))
+ {}
+ /*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); }
+ /*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
+ /*virtual*/ void onDelete(LLNotificationPtr p);
+ bool processNotification(const LLNotificationPtr& p);
};
class LLHandlerUtil
{
public:
/**
- * Checks sufficient conditions to log notification message to IM session.
- */
- static bool canLogToIM(const LLNotificationPtr& notification);
-
- /**
- * Checks sufficient conditions to log notification message to nearby chat session.
- */
- static bool canLogToNearbyChat(const LLNotificationPtr& notification);
-
- /**
- * Checks sufficient conditions to spawn IM session.
- */
- static bool canSpawnIMSession(const LLNotificationPtr& notification);
-
- /**
- * Checks sufficient conditions to add notification toast panel IM floater.
- */
- static bool canAddNotifPanelToIM(const LLNotificationPtr& notification);
-
- /**
- * Checks whether notification can be used multiple times or not.
- */
- static bool isNotificationReusable(const LLNotificationPtr& notification);
-
- /**
- * Checks if passed notification can create IM session and be written into it.
- *
- * This method uses canLogToIM() & canSpawnIMSession().
- */
- static bool canSpawnSessionAndLogToIM(const LLNotificationPtr& notification);
-
- /**
- * Checks if passed notification can create toast.
- */
- static bool canSpawnToast(const LLNotificationPtr& notification);
-
- /**
* Determines whether IM floater is opened.
*/
static bool isIMFloaterOpened(const LLNotificationPtr& notification);
/**
- * Determines whether IM floater is focused.
- */
- static bool isIMFloaterFocused(const LLNotificationPtr& notification);
-
- /**
* Writes notification message to IM session.
*/
static void logToIM(const EInstantMessage& session_type,
@@ -355,12 +299,7 @@ public:
/**
* Writes notification message to IM p2p session.
*/
- static void logToIMP2P(const LLNotificationPtr& notification);
-
- /**
- * Writes notification message to IM p2p session.
- */
- static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only);
+ static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only = false);
/**
* Writes group notice notification message to IM group session.
@@ -406,13 +345,6 @@ public:
*/
static void decIMMesageCounter(const LLNotificationPtr& notification);
-private:
-
- /**
- * Find IM floater based on "from_id"
- */
- static LLIMFloater* findIMFloater(const LLNotificationPtr& notification);
-
};
}
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index 7c6287967a..1494ac6b5c 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -54,7 +54,8 @@ void LLSysHandler::init()
sExclusiveNotificationGroups.push_back(online_offline_group);
}
-LLSysHandler::LLSysHandler()
+LLSysHandler::LLSysHandler(const std::string& name, const std::string& notification_type)
+: LLNotificationChannel(name, "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, notification_type))
{
if(sExclusiveNotificationGroups.empty())
{
@@ -110,131 +111,15 @@ void LLSysHandler::removeExclusiveNotifications(const LLNotificationPtr& notif)
}
}
-const static std::string GRANTED_MODIFY_RIGHTS("GrantedModifyRights"),
- REVOKED_MODIFY_RIGHTS("RevokedModifyRights"),
- OBJECT_GIVE_ITEM("ObjectGiveItem"),
- OBJECT_GIVE_ITEM_UNKNOWN_USER("ObjectGiveItemUnknownUser"),
- PAYMENT_RECEIVED("PaymentReceived"),
- PAYMENT_SENT("PaymentSent"),
- ADD_FRIEND_WITH_MESSAGE("AddFriendWithMessage"),
- USER_GIVE_ITEM("UserGiveItem"),
- INVENTORY_ACCEPTED("InventoryAccepted"),
- INVENTORY_DECLINED("InventoryDeclined"),
- OFFER_FRIENDSHIP("OfferFriendship"),
- FRIENDSHIP_ACCEPTED("FriendshipAccepted"),
- FRIENDSHIP_OFFERED("FriendshipOffered"),
- FRIENDSHIP_ACCEPTED_BYME("FriendshipAcceptedByMe"),
- FRIENDSHIP_DECLINED_BYME("FriendshipDeclinedByMe"),
- FRIEND_ONLINE("FriendOnline"), FRIEND_OFFLINE("FriendOffline"),
- SERVER_OBJECT_MESSAGE("ServerObjectMessage"),
- TELEPORT_OFFERED("TeleportOffered"),
- TELEPORT_OFFER_SENT("TeleportOfferSent"),
- IM_SYSTEM_MESSAGE_TIP("IMSystemMessageTip");
-
-
-// static
-bool LLHandlerUtil::canLogToIM(const LLNotificationPtr& notification)
-{
- return GRANTED_MODIFY_RIGHTS == notification->getName()
- || REVOKED_MODIFY_RIGHTS == notification->getName()
- || PAYMENT_RECEIVED == notification->getName()
- || PAYMENT_SENT == notification->getName()
- || OFFER_FRIENDSHIP == notification->getName()
- || FRIENDSHIP_OFFERED == notification->getName()
- || FRIENDSHIP_ACCEPTED == notification->getName()
- || FRIENDSHIP_ACCEPTED_BYME == notification->getName()
- || FRIENDSHIP_DECLINED_BYME == notification->getName()
- || SERVER_OBJECT_MESSAGE == notification->getName()
- || INVENTORY_ACCEPTED == notification->getName()
- || INVENTORY_DECLINED == notification->getName()
- || USER_GIVE_ITEM == notification->getName()
- || TELEPORT_OFFERED == notification->getName()
- || TELEPORT_OFFER_SENT == notification->getName()
- || IM_SYSTEM_MESSAGE_TIP == notification->getName();
-}
-
-// static
-bool LLHandlerUtil::canLogToNearbyChat(const LLNotificationPtr& notification)
-{
- return notification->getType() == "notifytip"
- && FRIEND_ONLINE != notification->getName()
- && FRIEND_OFFLINE != notification->getName()
- && INVENTORY_ACCEPTED != notification->getName()
- && INVENTORY_DECLINED != notification->getName()
- && IM_SYSTEM_MESSAGE_TIP != notification->getName();
-}
-
-// static
-bool LLHandlerUtil::canSpawnIMSession(const LLNotificationPtr& notification)
-{
- return OFFER_FRIENDSHIP == notification->getName()
- || USER_GIVE_ITEM == notification->getName()
- || TELEPORT_OFFERED == notification->getName();
-}
-
-// static
-bool LLHandlerUtil::canAddNotifPanelToIM(const LLNotificationPtr& notification)
-{
- return OFFER_FRIENDSHIP == notification->getName()
- || USER_GIVE_ITEM == notification->getName()
- || TELEPORT_OFFERED == notification->getName();
-}
-
// static
-bool LLHandlerUtil::isNotificationReusable(const LLNotificationPtr& notification)
-{
- return OFFER_FRIENDSHIP == notification->getName()
- || USER_GIVE_ITEM == notification->getName()
- || TELEPORT_OFFERED == notification->getName();
-}
-
-// static
-bool LLHandlerUtil::canSpawnSessionAndLogToIM(const LLNotificationPtr& notification)
-{
- return canLogToIM(notification) && canSpawnIMSession(notification);
-}
-
-// static
-bool LLHandlerUtil::canSpawnToast(const LLNotificationPtr& notification)
+bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification)
{
- if(INVENTORY_DECLINED == notification->getName()
- || INVENTORY_ACCEPTED == notification->getName())
- {
- // return false for inventory accepted/declined notifications if respective IM window is open (EXT-5909)
- return ! isIMFloaterOpened(notification);
- }
-
- if(FRIENDSHIP_ACCEPTED == notification->getName())
- {
- // don't show FRIENDSHIP_ACCEPTED if IM window is opened and focused - EXT-6441
- return ! isIMFloaterFocused(notification);
- }
-
- if(OFFER_FRIENDSHIP == notification->getName()
- || USER_GIVE_ITEM == notification->getName()
- || TELEPORT_OFFERED == notification->getName())
- {
- // When ANY offer arrives, show toast, unless IM window is already open - EXT-5904
- return ! isIMFloaterOpened(notification);
- }
-
- return true;
-}
+ bool res = false;
-// static
-LLIMFloater* LLHandlerUtil::findIMFloater(const LLNotificationPtr& notification)
-{
LLUUID from_id = notification->getPayload()["from_id"];
LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id);
- return LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
-}
-
-// static
-bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification)
-{
- bool res = false;
+ LLIMFloater* im_floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
- LLIMFloater* im_floater = findIMFloater(notification);
if (im_floater != NULL)
{
res = im_floater->getVisible() == TRUE;
@@ -243,19 +128,6 @@ bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification)
return res;
}
-bool LLHandlerUtil::isIMFloaterFocused(const LLNotificationPtr& notification)
-{
- bool res = false;
-
- LLIMFloater* im_floater = findIMFloater(notification);
- if (im_floater != NULL)
- {
- res = im_floater->hasFocus() == TRUE;
- }
-
- return res;
-}
-
// static
void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
const std::string& session_name, const std::string& from_name,
@@ -317,12 +189,6 @@ void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
}
}
-// static
-void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification)
-{
- logToIMP2P(notification, false);
-}
-
void log_name_callback(const std::string& full_name, const std::string& from_name,
const std::string& message, const LLUUID& from_id)
@@ -334,9 +200,6 @@ void log_name_callback(const std::string& full_name, const std::string& from_nam
// static
void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only)
{
- // don't create IM p2p session with objects, it's necessary condition to log
- if (notification->getName() != OBJECT_GIVE_ITEM)
- {
LLUUID from_id = notification->getPayload()["from_id"];
if (from_id.isNull())
@@ -354,7 +217,6 @@ void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_fi
gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id));
}
}
-}
// static
void LLHandlerUtil::logGroupNoticeToIMGroup(
@@ -489,14 +351,10 @@ void LLHandlerUtil::decIMMesageCounter(const LLNotificationPtr& notification)
LLUUID from_id = notification->getPayload()["from_id"];
LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id);
- LLIMModel::LLIMSession * session = LLIMModel::getInstance()->findIMSession(
- session_id);
+ LLIMModel::LLIMSession * session = LLIMModel::getInstance()->findIMSession(session_id);
- if (session == NULL)
+ if (session)
{
- return;
- }
-
LLSD arg;
arg["session_id"] = session_id;
session->mNumUnread--;
@@ -505,3 +363,5 @@ void LLHandlerUtil::decIMMesageCounter(const LLNotificationPtr& notification)
arg["participant_unread"] = session->mParticipantUnreadMessageCount;
LLIMModel::getInstance()->mNewMsgSignal(arg);
}
+}
+
diff --git a/indra/newview/llnotificationhinthandler.cpp b/indra/newview/llnotificationhinthandler.cpp
index f7163cb04f..271f418507 100644
--- a/indra/newview/llnotificationhinthandler.cpp
+++ b/indra/newview/llnotificationhinthandler.cpp
@@ -33,26 +33,6 @@
using namespace LLNotificationsUI;
-LLHintHandler::LLHintHandler()
-{
-}
-
-LLHintHandler::~LLHintHandler()
-{
-}
-
-bool LLHintHandler::processNotification(const LLSD& notify)
-{
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
- std::string sigtype = notify["sigtype"].asString();
- if (sigtype == "add" || sigtype == "load")
- {
- LLHints::show(notification);
- }
- else if (sigtype == "delete")
- {
- LLHints::hide(notification);
- }
- return false;
-}
+void LLHintHandler::onAdd(LLNotificationPtr p) { LLHints::show(p); }
+void LLHintHandler::onLoad(LLNotificationPtr p) { LLHints::show(p); }
+void LLHintHandler::onDelete(LLNotificationPtr p) { LLHints::hide(p); }
diff --git a/indra/newview/llnotificationmanager.cpp b/indra/newview/llnotificationmanager.cpp
index f792f53ac5..2862ad6962 100644
--- a/indra/newview/llnotificationmanager.cpp
+++ b/indra/newview/llnotificationmanager.cpp
@@ -42,107 +42,35 @@ using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
LLNotificationManager::LLNotificationManager()
{
- mNotifyHandlers.clear();
init();
}
//--------------------------------------------------------------------------
LLNotificationManager::~LLNotificationManager()
{
- BOOST_FOREACH(listener_pair_t& pair, mChannelListeners)
- {
- pair.second.disconnect();
- }
}
//--------------------------------------------------------------------------
void LLNotificationManager::init()
{
- LLNotificationChannel::buildChannel("Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notify"));
- LLNotificationChannel::buildChannel("NotificationTips", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notifytip"));
- LLNotificationChannel::buildChannel("Group Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "groupnotify"));
- LLNotificationChannel::buildChannel("Alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert"));
- LLNotificationChannel::buildChannel("AlertModal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal"));
- LLNotificationChannel::buildChannel("IM Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notifytoast"));
- LLNotificationChannel::buildChannel("Offer", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "offer"));
- LLNotificationChannel::buildChannel("Hints", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "hint"));
- LLNotificationChannel::buildChannel("Browser", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "browser"));
- LLNotificationChannel::buildChannel("Outbox", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "outbox"));
+ mChannels.push_back(new LLScriptHandler());
+ mChannels.push_back(new LLTipHandler());
+ mChannels.push_back(new LLGroupHandler());
+ mChannels.push_back(new LLAlertHandler("Alerts", "alert", false));
+ mChannels.push_back(new LLAlertHandler("AlertModal", "alertmodal", true));
+ mChannels.push_back(new LLOfferHandler());
+ mChannels.push_back(new LLHintHandler());
+ mChannels.push_back(new LLBrowserNotification());
+ mChannels.push_back(new LLOutboxNotification());
+ mChannels.push_back(new LLIMHandler());
- mChannelListeners["Notifications"] = LLNotifications::instance().getChannel("Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
- mChannelListeners["NotificationTips"] = LLNotifications::instance().getChannel("NotificationTips")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
- mChannelListeners["Group Notifications"] = LLNotifications::instance().getChannel("Group Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
- mChannelListeners["Alerts"] = LLNotifications::instance().getChannel("Alerts")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
- mChannelListeners["AlertModal"] = LLNotifications::instance().getChannel("AlertModal")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
- mChannelListeners["IM Notifications"] = LLNotifications::instance().getChannel("IM Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
- mChannelListeners["Offer"] = LLNotifications::instance().getChannel("Offer")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
- mChannelListeners["Hints"] = LLNotifications::instance().getChannel("Hints")->connectChanged(boost::bind(&LLHintHandler::processNotification, LLHintHandler::getInstance(), _1));
- mChannelListeners["Browser"] = LLNotifications::instance().getChannel("Browser")->connectChanged(boost::bind(&LLBrowserNotification::processNotification, LLBrowserNotification::getInstance(), _1));
- mChannelListeners["Outbox"] = LLNotifications::instance().getChannel("Outbox")->connectChanged(boost::bind(&LLOutboxNotification::processNotification, LLOutboxNotification::getInstance(), _1));
-
- mNotifyHandlers["notify"] = boost::shared_ptr<LLEventHandler>(new LLScriptHandler(NT_NOTIFY, LLSD()));
- mNotifyHandlers["notifytip"] = boost::shared_ptr<LLEventHandler>(new LLTipHandler(NT_NOTIFY, LLSD()));
- mNotifyHandlers["groupnotify"] = boost::shared_ptr<LLEventHandler>(new LLGroupHandler(NT_GROUPNOTIFY, LLSD()));
- mNotifyHandlers["alert"] = boost::shared_ptr<LLEventHandler>(new LLAlertHandler(NT_ALERT, LLSD()));
- mNotifyHandlers["alertmodal"] = boost::shared_ptr<LLEventHandler>(new LLAlertHandler(NT_ALERT, LLSD()));
- static_cast<LLAlertHandler*>(mNotifyHandlers["alertmodal"].get())->setAlertMode(true);
- mNotifyHandlers["notifytoast"] = boost::shared_ptr<LLEventHandler>(new LLIMHandler(NT_IMCHAT, LLSD()));
-
- mNotifyHandlers["nearbychat"] = boost::shared_ptr<LLEventHandler>(new LLNearbyChatHandler(NT_NEARBYCHAT, LLSD()));
- mNotifyHandlers["offer"] = boost::shared_ptr<LLEventHandler>(new LLOfferHandler(NT_OFFER, LLSD()));
-}
-
-//--------------------------------------------------------------------------
-bool LLNotificationManager::onNotification(const LLSD& notify)
-{
- LLSysHandler* handle = NULL;
-
- if (LLNotifications::destroyed())
- return false;
-
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
- if (!notification)
- return false;
-
- std::string notification_type = notification->getType();
- handle = static_cast<LLSysHandler*>(mNotifyHandlers[notification_type].get());
-
- if(!handle)
- return false;
-
- return handle->processNotification(notify);
+ mChatHandler = boost::shared_ptr<LLNearbyChatHandler>(new LLNearbyChatHandler());
}
//--------------------------------------------------------------------------
void LLNotificationManager::onChat(const LLChat& msg, const LLSD &args)
{
- // check ENotificationType argument
- switch(args["type"].asInteger())
- {
- case NT_NEARBYCHAT:
- {
- LLNearbyChatHandler* handle = dynamic_cast<LLNearbyChatHandler*>(mNotifyHandlers["nearbychat"].get());
-
- if(handle)
- handle->processChat(msg, args);
- }
- break;
- default: //no need to handle all enum types
- break;
- }
-}
-
-//--------------------------------------------------------------------------
-LLEventHandler* LLNotificationManager::getHandlerForNotification(std::string notification_type)
-{
- std::map<std::string, boost::shared_ptr<LLEventHandler> >::iterator it = mNotifyHandlers.find(notification_type);
-
- if(it != mNotifyHandlers.end())
- return (*it).second.get();
-
- return NULL;
+ if(mChatHandler)
+ mChatHandler->processChat(msg, args);
}
-//--------------------------------------------------------------------------
-
diff --git a/indra/newview/llnotificationmanager.h b/indra/newview/llnotificationmanager.h
index 27b6ba1c71..c8afdf9e46 100644
--- a/indra/newview/llnotificationmanager.h
+++ b/indra/newview/llnotificationmanager.h
@@ -28,8 +28,6 @@
#ifndef LL_LLNOTIFICATIONMANAGER_H
#define LL_LLNOTIFICATIONMANAGER_H
-#include "llevents.h"
-
#include "lluictrl.h"
#include "llnotificationhandler.h"
@@ -49,7 +47,6 @@ class LLToast;
class LLNotificationManager : public LLSingleton<LLNotificationManager>
{
typedef std::pair<std::string, LLEventHandler*> eventhandlers;
- typedef std::pair<const std::string, LLBoundListener> listener_pair_t;
public:
LLNotificationManager();
virtual ~LLNotificationManager();
@@ -59,22 +56,12 @@ public:
void init(void);
//TODO: combine processing and storage (*)
- // this method reacts on system notifications and calls an appropriate handler
- bool onNotification(const LLSD& notification);
-
// this method reacts on chat notifications and calls an appropriate handler
void onChat(const LLChat& msg, const LLSD &args);
- // get a handler for a certain type of notification
- LLEventHandler* getHandlerForNotification(std::string notification_type);
-
-
private:
- //TODO (*)
- std::map<std::string, boost::shared_ptr<LLEventHandler> > mNotifyHandlers;
- // cruft std::map<std::string, LLChatHandler*> mChatHandlers;
-
- std::map<std::string, LLBoundListener> mChannelListeners;
+ boost::shared_ptr<class LLNearbyChatHandler> mChatHandler;
+ std::vector<LLNotificationChannelPtr> mChannels;
};
}
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index 1552ed3346..52cc518968 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -40,10 +40,9 @@
using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
-LLOfferHandler::LLOfferHandler(e_notification_type type, const LLSD& id)
+LLOfferHandler::LLOfferHandler()
+: LLSysHandler("Offer", "offer")
{
- mType = type;
-
// Getting a Channel for our notifications
LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
if(channel)
@@ -68,52 +67,40 @@ void LLOfferHandler::initChannel()
}
//--------------------------------------------------------------------------
-bool LLOfferHandler::processNotification(const LLSD& notify)
+bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
{
if(mChannel.isDead())
{
return false;
}
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
- if(!notification)
- return false;
-
// arrange a channel on a screen
if(!mChannel.get()->getVisible())
{
initChannel();
}
- if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
- {
-
if( notification->getPayload().has("give_inventory_notification")
- && !notification->getPayload()["give_inventory_notification"] )
+ && notification->getPayload()["give_inventory_notification"].asBoolean() == false)
{
// This is an original inventory offer, so add a script floater
LLScriptFloaterManager::instance().onAddNotification(notification->getID());
}
else
{
- notification->setReusable(LLHandlerUtil::isNotificationReusable(notification));
+ bool add_notif_to_im = notification->canLogToIM() && notification->hasFormElements();
+
+ notification->setReusable(add_notif_to_im);
LLUUID session_id;
- if (LLHandlerUtil::canSpawnIMSession(notification))
+ if (add_notif_to_im)
{
const std::string name = LLHandlerUtil::getSubstitutionName(notification);
LLUUID from_id = notification->getPayload()["from_id"];
session_id = LLHandlerUtil::spawnIMSession(name, from_id);
- }
-
- bool show_toast = LLHandlerUtil::canSpawnToast(notification);
- bool add_notid_to_im = LLHandlerUtil::canAddNotifPanelToIM(notification);
- if (add_notid_to_im)
- {
LLHandlerUtil::addNotifPanelToIM(notification);
}
@@ -122,46 +109,35 @@ bool LLOfferHandler::processNotification(const LLSD& notify)
{
LLNotificationsUtil::cancel(notification);
}
- else if(show_toast)
+ else if(!notification->canLogToIM() || !LLHandlerUtil::isIMFloaterOpened(notification))
{
LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
// don't close notification on panel destroy since it will be used by IM floater
- notify_box->setCloseNotificationOnDestroy(!add_notid_to_im);
+ notify_box->setCloseNotificationOnDestroy(!add_notif_to_im);
LLToast::Params p;
p.notif_id = notification->getID();
p.notification = notification;
p.panel = notify_box;
- p.on_delete_toast = boost::bind(&LLOfferHandler::onDeleteToast, this, _1);
// we not save offer notifications to the syswell floater that should be added to the IM floater
- p.can_be_stored = !add_notid_to_im;
+ p.can_be_stored = !add_notif_to_im;
LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
if(channel)
channel->addToast(p);
-
- // if we not add notification to IM - add it to notification well
- if (!add_notid_to_im)
- {
- // send a signal to the counter manager
- mNewNotificationSignal();
- }
}
- if (LLHandlerUtil::canLogToIM(notification))
+ if (notification->canLogToIM())
{
// log only to file if notif panel can be embedded to IM and IM is opened
- if (add_notid_to_im && LLHandlerUtil::isIMFloaterOpened(notification))
- {
- LLHandlerUtil::logToIMP2P(notification, true);
+ bool file_only = add_notif_to_im && LLHandlerUtil::isIMFloaterOpened(notification);
+ LLHandlerUtil::logToIMP2P(notification, file_only);
}
- else
- {
- LLHandlerUtil::logToIMP2P(notification);
}
+
+ return false;
}
- }
- }
- else if (notify["sigtype"].asString() == "delete")
+
+/*virtual*/ void LLOfferHandler::onDelete(LLNotificationPtr notification)
{
if( notification->getPayload().has("give_inventory_notification")
&& !notification->getPayload()["give_inventory_notification"] )
@@ -171,7 +147,8 @@ bool LLOfferHandler::processNotification(const LLSD& notify)
}
else
{
- if (LLHandlerUtil::canAddNotifPanelToIM(notification)
+ if (notification->canLogToIM()
+ && notification->hasFormElements()
&& !LLHandlerUtil::isIMFloaterOpened(notification))
{
LLHandlerUtil::decIMMesageCounter(notification);
@@ -180,34 +157,15 @@ bool LLOfferHandler::processNotification(const LLSD& notify)
}
}
- return false;
-}
-
-//--------------------------------------------------------------------------
-
-void LLOfferHandler::onDeleteToast(LLToast* toast)
-{
- if (!LLHandlerUtil::canAddNotifPanelToIM(toast->getNotification()))
- {
- // send a signal to the counter manager
- mDelNotificationSignal();
- }
-
- // send a signal to a listener to let him perform some action
- // in this case listener is a SysWellWindow and it will remove a corresponding item from its list
- mNotificationIDSignal(toast->getNotificationID());
-}
-
//--------------------------------------------------------------------------
void LLOfferHandler::onRejectToast(LLUUID& id)
{
LLNotificationPtr notification = LLNotifications::instance().find(id);
if (notification
- && LLNotificationManager::getInstance()->getHandlerForNotification(
- notification->getType()) == this
+ && mItems.find(notification) != mItems.end()
// don't delete notification since it may be used by IM floater
- && !LLHandlerUtil::canAddNotifPanelToIM(notification))
+ && (!notification->canLogToIM() || !notification->hasFormElements()))
{
LLNotifications::instance().cancel(notification);
}
diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index 995915206b..8472f9b2ae 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -37,21 +37,16 @@
using namespace LLNotificationsUI;
-static const std::string SCRIPT_DIALOG ("ScriptDialog");
-static const std::string SCRIPT_DIALOG_GROUP ("ScriptDialogGroup");
-static const std::string SCRIPT_LOAD_URL ("LoadWebPage");
-
//--------------------------------------------------------------------------
-LLScriptHandler::LLScriptHandler(e_notification_type type, const LLSD& id)
+LLScriptHandler::LLScriptHandler()
+: LLSysHandler("Notifications", "notify")
{
- mType = type;
-
// Getting a Channel for our notifications
LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
if(channel)
{
channel->setControlHovering(true);
- channel->setOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1));
+ channel->addOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1));
mChannel = channel->getHandle();
}
}
@@ -70,32 +65,25 @@ void LLScriptHandler::initChannel()
}
//--------------------------------------------------------------------------
-bool LLScriptHandler::processNotification(const LLSD& notify)
+bool LLScriptHandler::processNotification(const LLNotificationPtr& notification)
{
if(mChannel.isDead())
{
return false;
}
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
- if(!notification)
- return false;
-
// arrange a channel on a screen
if(!mChannel.get()->getVisible())
{
initChannel();
}
- if(notify["sigtype"].asString() == "add")
- {
- if (LLHandlerUtil::canLogToIM(notification))
+ if (notification->canLogToIM())
{
LLHandlerUtil::logToIMP2P(notification);
}
- if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName() || SCRIPT_LOAD_URL == notification->getName())
+ if(notification->hasFormElements())
{
LLScriptFloaterManager::getInstance()->onAddNotification(notification->getID());
}
@@ -114,14 +102,15 @@ bool LLScriptHandler::processNotification(const LLSD& notify)
{
channel->addToast(p);
}
+ }
- // send a signal to the counter manager
- mNewNotificationSignal();
+ return false;
}
- }
- else if (notify["sigtype"].asString() == "delete")
+
+
+void LLScriptHandler::onDelete( LLNotificationPtr notification )
{
- if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName() || SCRIPT_LOAD_URL == notification->getName())
+ if(notification->hasFormElements())
{
LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID());
}
@@ -130,24 +119,17 @@ bool LLScriptHandler::processNotification(const LLSD& notify)
mChannel.get()->killToastByNotificationID(notification->getID());
}
}
- return false;
-}
+
//--------------------------------------------------------------------------
void LLScriptHandler::onDeleteToast(LLToast* toast)
{
- // send a signal to the counter manager
- mDelNotificationSignal();
-
// send a signal to a listener to let him perform some action
// in this case listener is a SysWellWindow and it will remove a corresponding item from its list
- mNotificationIDSignal(toast->getNotificationID());
-
LLNotificationPtr notification = LLNotifications::getInstance()->find(toast->getNotificationID());
- if( notification &&
- (SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName()) )
+ if( notification && notification->hasFormElements())
{
LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID());
}
@@ -158,9 +140,7 @@ void LLScriptHandler::onRejectToast(LLUUID& id)
{
LLNotificationPtr notification = LLNotifications::instance().find(id);
- if (notification
- && LLNotificationManager::getInstance()->getHandlerForNotification(
- notification->getType()) == this)
+ if (notification && mItems.find(notification) != mItems.end())
{
LLNotifications::instance().cancel(notification);
}
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index e397cfa046..f07109335d 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -41,15 +41,14 @@
using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
-LLTipHandler::LLTipHandler(e_notification_type type, const LLSD& id)
+LLTipHandler::LLTipHandler()
+: LLSysHandler("NotificationTips", "notifytip")
{
- mType = type;
-
// Getting a Channel for our notifications
LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
if(channel)
{
- channel->setOnRejectToastCallback(boost::bind(&LLTipHandler::onRejectToast, this, _1));
+ channel->addOnRejectToastCallback(boost::bind(&LLTipHandler::onRejectToast, this, _1));
mChannel = channel->getHandle();
}
}
@@ -68,28 +67,21 @@ void LLTipHandler::initChannel()
}
//--------------------------------------------------------------------------
-bool LLTipHandler::processNotification(const LLSD& notify)
+bool LLTipHandler::processNotification(const LLNotificationPtr& notification)
{
if(mChannel.isDead())
{
return false;
}
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
- if(!notification)
- return false;
-
// arrange a channel on a screen
if(!mChannel.get()->getVisible())
{
initChannel();
}
- if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
- {
// archive message in nearby chat
- if (LLHandlerUtil::canLogToNearbyChat(notification))
+ if (notification->canLogToChat())
{
LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM);
@@ -109,19 +101,18 @@ bool LLTipHandler::processNotification(const LLSD& notify)
session_name = name;
}
LLUUID from_id = notification->getPayload()["from_id"];
- if (LLHandlerUtil::canLogToIM(notification))
+ if (notification->canLogToIM())
{
LLHandlerUtil::logToIM(IM_NOTHING_SPECIAL, session_name, name,
notification->getMessage(), from_id, from_id);
}
- if (LLHandlerUtil::canSpawnIMSession(notification))
+ if (notification->canLogToIM() && notification->hasFormElements())
{
LLHandlerUtil::spawnIMSession(name, from_id);
}
- // don't spawn toast for inventory accepted/declined offers if respective IM window is open (EXT-5909)
- if (!LLHandlerUtil::canSpawnToast(notification))
+ if (notification->canLogToIM() && LLHandlerUtil::isIMFloaterOpened(notification))
{
return false;
}
@@ -144,25 +135,18 @@ bool LLTipHandler::processNotification(const LLSD& notify)
}
else if (notify["sigtype"].asString() == "delete")
{
- mChannel.get()->killToastByNotificationID(notification->getID());
+ mChannel->killToastByNotificationID(notification->getID());
}
return false;
}
//--------------------------------------------------------------------------
-void LLTipHandler::onDeleteToast(LLToast* toast)
-{
-}
-
-//--------------------------------------------------------------------------
void LLTipHandler::onRejectToast(const LLUUID& id)
{
LLNotificationPtr notification = LLNotifications::instance().find(id);
- if (notification
- && LLNotificationManager::getInstance()->getHandlerForNotification(
- notification->getType()) == this)
+ if (notification && mItems.find(notification) != mItems.end())
{
LLNotifications::instance().cancel(notification);
}
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 85626d8783..096e714981 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -28,6 +28,7 @@
#include "lloutputmonitorctrl.h"
// library includes
+#include "llfloaterreg.h"
#include "llui.h"
// viewer includes
@@ -241,6 +242,17 @@ void LLOutputMonitorCtrl::draw()
gl_rect_2d(0, monh, monw, 0, sColorBound, FALSE);
}
+// virtual
+BOOL LLOutputMonitorCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
+{
+ if (mSpeakerId != gAgentID)
+ {
+ LLFloaterReg::showInstance("floater_voice_volume", LLSD().with("avatar_id", mSpeakerId));
+ }
+
+ return TRUE;
+}
+
void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id/* = LLUUID::null*/)
{
if (speaker_id.isNull() && mSpeakerId.notNull())
diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h
index 2d23753d46..7b02e84744 100644
--- a/indra/newview/lloutputmonitorctrl.h
+++ b/indra/newview/lloutputmonitorctrl.h
@@ -68,6 +68,7 @@ public:
// llview overrides
virtual void draw();
+ virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
void setPower(F32 val);
F32 getPower(F32 val) const { return mPower; }
diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp
index 5c85ec438c..d2dff63948 100644
--- a/indra/newview/llpanelblockedlist.cpp
+++ b/indra/newview/llpanelblockedlist.cpp
@@ -69,8 +69,6 @@ BOOL LLPanelBlockedList::postBuild()
mBlockedList = getChild<LLScrollListCtrl>("blocked");
mBlockedList->setCommitOnSelectionChange(TRUE);
- childSetCommitCallback("back", boost::bind(&LLPanelBlockedList::onBackBtnClick, this), NULL);
-
LLMuteList::getInstance()->addObserver(this);
refreshBlockedList();
@@ -99,7 +97,8 @@ void LLPanelBlockedList::selectBlocked(const LLUUID& mute_id)
void LLPanelBlockedList::showPanelAndSelect(const LLUUID& idToSelect)
{
- LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD().with(BLOCKED_PARAM_NAME, idToSelect));
+ LLFloaterSidePanelContainer::showPanel("people", "panel_people",
+ LLSD().with("people_panel_tab_name", "blocked_panel").with(BLOCKED_PARAM_NAME, idToSelect));
}
@@ -130,17 +129,6 @@ void LLPanelBlockedList::updateButtons()
getChildView("Unblock")->setEnabled(hasSelected);
}
-
-
-void LLPanelBlockedList::onBackBtnClick()
-{
- LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent());
- if(parent)
- {
- parent->openPreviousPanel();
- }
-}
-
void LLPanelBlockedList::onRemoveBtnClick()
{
std::string name = mBlockedList->getSelectedItemLabel();
diff --git a/indra/newview/llpanelblockedlist.h b/indra/newview/llpanelblockedlist.h
index 74ad82e32d..97236ecdbf 100644
--- a/indra/newview/llpanelblockedlist.h
+++ b/indra/newview/llpanelblockedlist.h
@@ -68,7 +68,6 @@ private:
void updateButtons();
// UI callbacks
- void onBackBtnClick();
void onRemoveBtnClick();
void onPickBtnClick();
void onBlockByNameClick();
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 98ea680504..1efd1c3d9c 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -738,15 +738,7 @@ const std::string& LLTaskCategoryBridge::getDisplayName() const
if (cat)
{
- // Localize "Contents" folder.
- if (cat->getParentUUID().isNull() && cat->getName() == "Contents")
- {
- mDisplayName.assign(LLTrans::getString("ViewerObjectContents"));
- }
- else
- {
- mDisplayName.assign(cat->getName());
- }
+ mDisplayName.assign(cat->getName());
}
return mDisplayName;
@@ -1552,6 +1544,7 @@ void LLPanelObjectInventory::reset()
p.parent_panel = this;
p.tool_tip= LLTrans::getString("PanelContentsTooltip");
p.listener = LLTaskInvFVBridge::createObjectBridge(this, NULL);
+ p.folder_indentation = -14; // subtract space normally reserved for folder expanders
mFolders = LLUICtrlFactory::create<LLFolderView>(p);
// this ensures that we never say "searching..." or "no items found"
mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
@@ -1630,10 +1623,11 @@ void LLPanelObjectInventory::updateInventory()
LLInventoryObject* inventory_root = objectp->getInventoryRoot();
LLInventoryObject::object_list_t contents;
objectp->getInventoryContents(contents);
- if (inventory_root)
+ mHaveInventory = TRUE;
+
+ if (inventory_root && !contents.empty())
{
createFolderViews(inventory_root, contents);
- mHaveInventory = TRUE;
mIsInventoryEmpty = FALSE;
mFolders->setEnabled(TRUE);
}
@@ -1641,7 +1635,6 @@ void LLPanelObjectInventory::updateInventory()
{
// TODO: create an empty inventory
mIsInventoryEmpty = TRUE;
- mHaveInventory = TRUE;
}
}
else
@@ -1693,19 +1686,19 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root
bridge = LLTaskInvFVBridge::createObjectBridge(this, inventory_root);
if(bridge)
{
- LLFolderViewFolder* new_folder = NULL;
- LLFolderViewFolder::Params p;
- p.name = inventory_root->getName();
- p.icon = LLUI::getUIImage("Inv_FolderClosed");
- p.icon_open = LLUI::getUIImage("Inv_FolderOpen");
- p.root = mFolders;
- p.listener = bridge;
- p.tool_tip = p.name;
- new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p);
- new_folder->addToFolder(mFolders, mFolders);
- new_folder->toggleOpen();
-
- createViewsForCategory(&contents, inventory_root, new_folder);
+ //LLFolderViewFolder* new_folder = NULL;
+ //LLFolderViewFolder::Params p;
+ //p.name = inventory_root->getName();
+ //p.icon = LLUI::getUIImage("Inv_FolderClosed");
+ //p.icon_open = LLUI::getUIImage("Inv_FolderOpen");
+ //p.root = mFolders;
+ //p.listener = bridge;
+ //p.tool_tip = p.name;
+ //new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p);
+ //new_folder->addToFolder(mFolders, mFolders);
+ //new_folder->toggleOpen();
+
+ createViewsForCategory(&contents, inventory_root, mFolders);
}
}
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index f1380e7a36..9b06d05b4b 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -72,6 +72,7 @@ static const std::string NEARBY_TAB_NAME = "nearby_panel";
static const std::string FRIENDS_TAB_NAME = "friends_panel";
static const std::string GROUP_TAB_NAME = "groups_panel";
static const std::string RECENT_TAB_NAME = "recent_panel";
+static const std::string BLOCKED_TAB_NAME = "blocked_panel"; // blocked avatars
static const std::string COLLAPSED_BY_USER = "collapsed_by_user";
@@ -492,26 +493,37 @@ public:
LLPanelPeople::LLPanelPeople()
: LLPanel(),
- mFilterSubString(LLStringUtil::null),
- mFilterSubStringOrig(LLStringUtil::null),
- mFilterEditor(NULL),
mTabContainer(NULL),
mOnlineFriendList(NULL),
mAllFriendList(NULL),
mNearbyList(NULL),
mRecentList(NULL),
mGroupList(NULL),
- mNearbyGearButton(NULL),
- mFriendsGearButton(NULL),
- mGroupsGearButton(NULL),
- mRecentGearButton(NULL),
mMiniMap(NULL)
{
mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::updateFriendList, this));
mNearbyListUpdater = new LLNearbyListUpdater(boost::bind(&LLPanelPeople::updateNearbyList, this));
mRecentListUpdater = new LLRecentListUpdater(boost::bind(&LLPanelPeople::updateRecentList, this));
mButtonsUpdater = new LLButtonsUpdater(boost::bind(&LLPanelPeople::updateButtons, this));
- mCommitCallbackRegistrar.add("People.addFriend", boost::bind(&LLPanelPeople::onAddFriendButtonClicked, this));
+
+ mCommitCallbackRegistrar.add("People.AddFriend", boost::bind(&LLPanelPeople::onAddFriendButtonClicked, this));
+ mCommitCallbackRegistrar.add("People.AddFriendWizard", boost::bind(&LLPanelPeople::onAddFriendWizButtonClicked, this));
+ mCommitCallbackRegistrar.add("People.DelFriend", boost::bind(&LLPanelPeople::onDeleteFriendButtonClicked, this));
+ mCommitCallbackRegistrar.add("People.Group.Minus", boost::bind(&LLPanelPeople::onGroupMinusButtonClicked, this));
+ mCommitCallbackRegistrar.add("People.Chat", boost::bind(&LLPanelPeople::onChatButtonClicked, this));
+ mCommitCallbackRegistrar.add("People.Gear", boost::bind(&LLPanelPeople::onGearButtonClicked, this, _1));
+
+ mCommitCallbackRegistrar.add("People.Group.Plus.Action", boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked, this, _2));
+ mCommitCallbackRegistrar.add("People.Friends.ViewSort.Action", boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemClicked, this, _2));
+ mCommitCallbackRegistrar.add("People.Nearby.ViewSort.Action", boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemClicked, this, _2));
+ mCommitCallbackRegistrar.add("People.Groups.ViewSort.Action", boost::bind(&LLPanelPeople::onGroupsViewSortMenuItemClicked, this, _2));
+ mCommitCallbackRegistrar.add("People.Recent.ViewSort.Action", boost::bind(&LLPanelPeople::onRecentViewSortMenuItemClicked, this, _2));
+
+ mEnableCallbackRegistrar.add("People.Friends.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemCheck, this, _2));
+ mEnableCallbackRegistrar.add("People.Recent.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onRecentViewSortMenuItemCheck, this, _2));
+ mEnableCallbackRegistrar.add("People.Nearby.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemCheck, this, _2));
+
+ mEnableCallbackRegistrar.add("People.Group.Plus.Validate", boost::bind(&LLPanelPeople::onGroupPlusButtonValidate, this));
}
LLPanelPeople::~LLPanelPeople()
@@ -525,13 +537,6 @@ LLPanelPeople::~LLPanelPeople()
{
LLVoiceClient::getInstance()->removeObserver(this);
}
-
- if (mGroupPlusMenuHandle.get()) mGroupPlusMenuHandle.get()->die();
- if (mNearbyViewSortMenuHandle.get()) mNearbyViewSortMenuHandle.get()->die();
- if (mNearbyViewSortMenuHandle.get()) mNearbyViewSortMenuHandle.get()->die();
- if (mGroupsViewSortMenuHandle.get()) mGroupsViewSortMenuHandle.get()->die();
- if (mRecentViewSortMenuHandle.get()) mRecentViewSortMenuHandle.get()->die();
-
}
void LLPanelPeople::onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LLSD& param, LLAvatarList* avatar_list)
@@ -553,11 +558,15 @@ void LLPanelPeople::onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LL
BOOL LLPanelPeople::postBuild()
{
- mFilterEditor = getChild<LLFilterEditor>("filter_input");
- mFilterEditor->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
+ getChild<LLFilterEditor>("nearby_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
+ getChild<LLFilterEditor>("friends_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
+ getChild<LLFilterEditor>("groups_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
+ getChild<LLFilterEditor>("recent_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
mTabContainer = getChild<LLTabContainer>("tabs");
mTabContainer->setCommitCallback(boost::bind(&LLPanelPeople::onTabSelected, this, _2));
+ mSavedFilters.resize(mTabContainer->getTabCount());
+ mSavedOriginalFilters.resize(mTabContainer->getTabCount());
LLPanel* friends_tab = getChild<LLPanel>(FRIENDS_TAB_NAME);
// updater is active only if panel is visible to user.
@@ -601,14 +610,6 @@ BOOL LLPanelPeople::postBuild()
setSortOrder(mAllFriendList, (ESortOrder)gSavedSettings.getU32("FriendsSortOrder"), false);
setSortOrder(mNearbyList, (ESortOrder)gSavedSettings.getU32("NearbyPeopleSortOrder"), false);
- LLPanel* groups_panel = getChild<LLPanel>(GROUP_TAB_NAME);
- groups_panel->childSetAction("activate_btn", boost::bind(&LLPanelPeople::onActivateButtonClicked, this));
- groups_panel->childSetAction("plus_btn", boost::bind(&LLPanelPeople::onGroupPlusButtonClicked, this));
-
- LLPanel* friends_panel = getChild<LLPanel>(FRIENDS_TAB_NAME);
- friends_panel->childSetAction("add_btn", boost::bind(&LLPanelPeople::onAddFriendWizButtonClicked, this));
- friends_panel->childSetAction("del_btn", boost::bind(&LLPanelPeople::onDeleteFriendButtonClicked, this));
-
mOnlineFriendList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1));
mAllFriendList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1));
mNearbyList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1));
@@ -637,70 +638,9 @@ BOOL LLPanelPeople::postBuild()
accordion_tab->setDropDownStateChangedCallback(
boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _1, _2, mOnlineFriendList));
- buttonSetAction("view_profile_btn", boost::bind(&LLPanelPeople::onViewProfileButtonClicked, this));
- buttonSetAction("group_info_btn", boost::bind(&LLPanelPeople::onGroupInfoButtonClicked, this));
- buttonSetAction("chat_btn", boost::bind(&LLPanelPeople::onChatButtonClicked, this));
- buttonSetAction("im_btn", boost::bind(&LLPanelPeople::onImButtonClicked, this));
- buttonSetAction("call_btn", boost::bind(&LLPanelPeople::onCallButtonClicked, this));
- buttonSetAction("group_call_btn", boost::bind(&LLPanelPeople::onGroupCallButtonClicked, this));
- buttonSetAction("teleport_btn", boost::bind(&LLPanelPeople::onTeleportButtonClicked, this));
- buttonSetAction("share_btn", boost::bind(&LLPanelPeople::onShareButtonClicked, this));
-
// Must go after setting commit callback and initializing all pointers to children.
mTabContainer->selectTabByName(NEARBY_TAB_NAME);
- // Create menus.
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
- LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
-
- registrar.add("People.Group.Plus.Action", boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked, this, _2));
- registrar.add("People.Group.Minus.Action", boost::bind(&LLPanelPeople::onGroupMinusButtonClicked, this));
- registrar.add("People.Friends.ViewSort.Action", boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemClicked, this, _2));
- registrar.add("People.Nearby.ViewSort.Action", boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemClicked, this, _2));
- registrar.add("People.Groups.ViewSort.Action", boost::bind(&LLPanelPeople::onGroupsViewSortMenuItemClicked, this, _2));
- registrar.add("People.Recent.ViewSort.Action", boost::bind(&LLPanelPeople::onRecentViewSortMenuItemClicked, this, _2));
-
- enable_registrar.add("People.Group.Minus.Enable", boost::bind(&LLPanelPeople::isRealGroup, this));
- enable_registrar.add("People.Friends.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemCheck, this, _2));
- enable_registrar.add("People.Recent.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onRecentViewSortMenuItemCheck, this, _2));
- enable_registrar.add("People.Nearby.ViewSort.CheckItem", boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemCheck, this, _2));
-
- mNearbyGearButton = getChild<LLMenuButton>("nearby_view_sort_btn");
- mFriendsGearButton = getChild<LLMenuButton>("friends_viewsort_btn");
- mGroupsGearButton = getChild<LLMenuButton>("groups_viewsort_btn");
- mRecentGearButton = getChild<LLMenuButton>("recent_viewsort_btn");
-
- LLMenuGL* plus_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_group_plus.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- mGroupPlusMenuHandle = plus_menu->getHandle();
-
- LLToggleableMenu* nearby_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_nearby_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- if(nearby_view_sort)
- {
- mNearbyViewSortMenuHandle = nearby_view_sort->getHandle();
- mNearbyGearButton->setMenu(nearby_view_sort);
- }
-
- LLToggleableMenu* friend_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_friends_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- if(friend_view_sort)
- {
- mFriendsViewSortMenuHandle = friend_view_sort->getHandle();
- mFriendsGearButton->setMenu(friend_view_sort);
- }
-
- LLToggleableMenu* group_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_groups_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- if(group_view_sort)
- {
- mGroupsViewSortMenuHandle = group_view_sort->getHandle();
- mGroupsGearButton->setMenu(group_view_sort);
- }
-
- LLToggleableMenu* recent_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_recent_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- if(recent_view_sort)
- {
- mRecentViewSortMenuHandle = recent_view_sort->getHandle();
- mRecentGearButton->setMenu(recent_view_sort);
- }
-
LLVoiceClient::getInstance()->addObserver(this);
// call this method in case some list is empty and buttons can be in inconsistent state
@@ -735,9 +675,11 @@ void LLPanelPeople::updateFriendListHelpText()
if (no_friends_text->getVisible())
{
//update help text for empty lists
- std::string message_name = mFilterSubString.empty() ? "no_friends_msg" : "no_filtered_friends_msg";
+ const std::string& filter = mSavedOriginalFilters[mTabContainer->getCurrentPanelIndex()];
+
+ std::string message_name = filter.empty() ? "no_friends_msg" : "no_filtered_friends_msg";
LLStringUtil::format_map_t args;
- args["[SEARCH_TERM]"] = LLURI::escape(mFilterSubStringOrig);
+ args["[SEARCH_TERM]"] = LLURI::escape(filter);
no_friends_text->setText(getString(message_name, args));
}
}
@@ -821,31 +763,9 @@ void LLPanelPeople::updateRecentList()
mRecentList->setDirty();
}
-void LLPanelPeople::buttonSetVisible(std::string btn_name, BOOL visible)
-{
- // To make sure we're referencing the right widget (a child of the button bar).
- LLButton* button = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name);
- button->setVisible(visible);
-}
-
-void LLPanelPeople::buttonSetEnabled(const std::string& btn_name, bool enabled)
-{
- // To make sure we're referencing the right widget (a child of the button bar).
- LLButton* button = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name);
- button->setEnabled(enabled);
-}
-
-void LLPanelPeople::buttonSetAction(const std::string& btn_name, const commit_signal_t::slot_type& cb)
-{
- // To make sure we're referencing the right widget (a child of the button bar).
- LLButton* button = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name);
- button->setClickedCallback(cb);
-}
-
void LLPanelPeople::updateButtons()
{
std::string cur_tab = getActiveTabName();
- bool nearby_tab_active = (cur_tab == NEARBY_TAB_NAME);
bool friends_tab_active = (cur_tab == FRIENDS_TAB_NAME);
bool group_tab_active = (cur_tab == GROUP_TAB_NAME);
//bool recent_tab_active = (cur_tab == RECENT_TAB_NAME);
@@ -856,28 +776,15 @@ void LLPanelPeople::updateButtons()
bool item_selected = (selected_uuids.size() == 1);
bool multiple_selected = (selected_uuids.size() >= 1);
- buttonSetVisible("group_info_btn", group_tab_active);
- buttonSetVisible("chat_btn", group_tab_active);
- buttonSetVisible("view_profile_btn", !group_tab_active);
- buttonSetVisible("im_btn", !group_tab_active);
- buttonSetVisible("call_btn", !group_tab_active);
- buttonSetVisible("group_call_btn", group_tab_active);
- buttonSetVisible("teleport_btn", friends_tab_active);
- buttonSetVisible("share_btn", nearby_tab_active || friends_tab_active);
-
if (group_tab_active)
{
- bool cur_group_active = true;
-
if (item_selected)
{
selected_id = mGroupList->getSelectedUUID();
- cur_group_active = (gAgent.getGroupID() == selected_id);
}
LLPanel* groups_panel = mTabContainer->getCurrentPanel();
- groups_panel->getChildView("activate_btn")->setEnabled(item_selected && !cur_group_active); // "none" or a non-active group selected
- groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull());
+ groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull()); // a real group selected
}
else
{
@@ -893,26 +800,20 @@ void LLPanelPeople::updateButtons()
LLPanel* cur_panel = mTabContainer->getCurrentPanel();
if (cur_panel)
{
- cur_panel->getChildView("add_friend_btn")->setEnabled(!is_friend);
+ if (cur_panel->hasChild("add_friend_btn", TRUE))
+ cur_panel->getChildView("add_friend_btn")->setEnabled(item_selected && !is_friend);
+
if (friends_tab_active)
{
- cur_panel->getChildView("del_btn")->setEnabled(multiple_selected);
+ cur_panel->getChildView("friends_del_btn")->setEnabled(multiple_selected);
+ }
+
+ if (!group_tab_active)
+ {
+ cur_panel->getChildView("gear_btn")->setEnabled(multiple_selected);
}
}
}
-
- bool enable_calls = LLVoiceClient::getInstance()->isVoiceWorking() && LLVoiceClient::getInstance()->voiceEnabled();
-
- buttonSetEnabled("view_profile_btn",item_selected);
- buttonSetEnabled("share_btn", item_selected);
- buttonSetEnabled("im_btn", multiple_selected); // allow starting the friends conference for multiple selection
- buttonSetEnabled("call_btn", multiple_selected && enable_calls);
- buttonSetEnabled("teleport_btn", multiple_selected && LLAvatarActions::canOfferTeleport(selected_uuids));
-
- bool none_group_selected = item_selected && selected_id.isNull();
- buttonSetEnabled("group_info_btn", !none_group_selected);
- buttonSetEnabled("group_call_btn", !none_group_selected && enable_calls);
- buttonSetEnabled("chat_btn", !none_group_selected);
}
std::string LLPanelPeople::getActiveTabName() const
@@ -943,6 +844,9 @@ LLUUID LLPanelPeople::getCurrentItemID() const
if (cur_tab == GROUP_TAB_NAME)
return mGroupList->getSelectedUUID();
+ if (cur_tab == BLOCKED_TAB_NAME)
+ return LLUUID::null; // FIXME?
+
llassert(0 && "unknown tab selected");
return LLUUID::null;
}
@@ -963,6 +867,8 @@ void LLPanelPeople::getCurrentItemIDs(uuid_vec_t& selected_uuids) const
mRecentList->getSelectedUUIDs(selected_uuids);
else if (cur_tab == GROUP_TAB_NAME)
mGroupList->getSelectedUUIDs(selected_uuids);
+ else if (cur_tab == BLOCKED_TAB_NAME)
+ selected_uuids.clear(); // FIXME?
else
llassert(0 && "unknown tab selected");
@@ -1031,49 +937,60 @@ void LLPanelPeople::setSortOrder(LLAvatarList* list, ESortOrder order, bool save
}
}
-bool LLPanelPeople::isRealGroup()
-{
- return getCurrentItemID() != LLUUID::null;
-}
-
void LLPanelPeople::onFilterEdit(const std::string& search_string)
{
- mFilterSubStringOrig = search_string;
- LLStringUtil::trimHead(mFilterSubStringOrig);
+ const S32 cur_tab_idx = mTabContainer->getCurrentPanelIndex();
+ std::string& filter = mSavedOriginalFilters[cur_tab_idx];
+ std::string& saved_filter = mSavedFilters[cur_tab_idx];
+
+ filter = search_string;
+ LLStringUtil::trimHead(filter);
+
// Searches are case-insensitive
- std::string search_upper = mFilterSubStringOrig;
+ std::string search_upper = filter;
LLStringUtil::toUpper(search_upper);
- if (mFilterSubString == search_upper)
+ if (saved_filter == search_upper)
return;
- mFilterSubString = search_upper;
+ saved_filter = search_upper;
- //store accordion tabs state before any manipulation with accordion tabs
- if(!mFilterSubString.empty())
+ // Apply new filter to the current tab.
+ const std::string cur_tab = getActiveTabName();
+ if (cur_tab == NEARBY_TAB_NAME)
+ {
+ mNearbyList->setNameFilter(filter);
+ }
+ else if (cur_tab == FRIENDS_TAB_NAME)
+ {
+ // store accordion tabs opened/closed state before any manipulation with accordion tabs
+ if (!saved_filter.empty())
{
notifyChildren(LLSD().with("action","store_state"));
}
-
- // Apply new filter.
- mNearbyList->setNameFilter(mFilterSubStringOrig);
- mOnlineFriendList->setNameFilter(mFilterSubStringOrig);
- mAllFriendList->setNameFilter(mFilterSubStringOrig);
- mRecentList->setNameFilter(mFilterSubStringOrig);
- mGroupList->setNameFilter(mFilterSubStringOrig);
+ mOnlineFriendList->setNameFilter(filter);
+ mAllFriendList->setNameFilter(filter);
setAccordionCollapsedByUser("tab_online", false);
setAccordionCollapsedByUser("tab_all", false);
-
showFriendsAccordionsIfNeeded();
- //restore accordion tabs state _after_ all manipulations...
- if(mFilterSubString.empty())
+ // restore accordion tabs state _after_ all manipulations
+ if(saved_filter.empty())
{
notifyChildren(LLSD().with("action","restore_state"));
}
}
+ else if (cur_tab == GROUP_TAB_NAME)
+ {
+ mGroupList->setNameFilter(filter);
+ }
+ else if (cur_tab == RECENT_TAB_NAME)
+ {
+ mRecentList->setNameFilter(filter);
+ }
+}
void LLPanelPeople::onTabSelected(const LLSD& param)
{
@@ -1081,11 +998,6 @@ void LLPanelPeople::onTabSelected(const LLSD& param)
updateButtons();
showFriendsAccordionsIfNeeded();
-
- if (GROUP_TAB_NAME == tab_name)
- mFilterEditor->setLabel(getString("groups_filter_label"));
- else
- mFilterEditor->setLabel(getString("people_filter_label"));
}
void LLPanelPeople::onAvatarListDoubleClicked(LLUICtrl* ctrl)
@@ -1127,12 +1039,6 @@ void LLPanelPeople::onAvatarListCommitted(LLAvatarList* list)
updateButtons();
}
-void LLPanelPeople::onViewProfileButtonClicked()
-{
- LLUUID id = getCurrentItemID();
- LLAvatarActions::showProfile(id);
-}
-
void LLPanelPeople::onAddFriendButtonClicked()
{
LLUUID id = getCurrentItemID();
@@ -1191,11 +1097,6 @@ void LLPanelPeople::onDeleteFriendButtonClicked()
}
}
-void LLPanelPeople::onGroupInfoButtonClicked()
-{
- LLGroupActions::show(getCurrentItemID());
-}
-
void LLPanelPeople::onChatButtonClicked()
{
LLUUID group_id = getCurrentItemID();
@@ -1203,6 +1104,14 @@ void LLPanelPeople::onChatButtonClicked()
LLGroupActions::startIM(group_id);
}
+void LLPanelPeople::onGearButtonClicked(LLUICtrl* btn)
+{
+ uuid_vec_t selected_uuids;
+ getCurrentItemIDs(selected_uuids);
+ // Spawn at bottom left corner of the button.
+ LLPanelPeopleMenus::gNearbyMenu.show(btn, selected_uuids, 0, 0);
+}
+
void LLPanelPeople::onImButtonClicked()
{
uuid_vec_t selected_uuids;
@@ -1219,11 +1128,6 @@ void LLPanelPeople::onImButtonClicked()
}
}
-void LLPanelPeople::onActivateButtonClicked()
-{
- LLGroupActions::activate(mGroupList->getSelectedUUID());
-}
-
// static
void LLPanelPeople::onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)
{
@@ -1231,19 +1135,15 @@ void LLPanelPeople::onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAv
LLAvatarActions::requestFriendshipDialog(ids[0], names[0].getCompleteName());
}
-void LLPanelPeople::onGroupPlusButtonClicked()
+bool LLPanelPeople::onGroupPlusButtonValidate()
{
if (!gAgent.canJoinGroups())
{
LLNotificationsUtil::add("JoinedTooManyGroups");
- return;
+ return false;
}
- LLMenuGL* plus_menu = (LLMenuGL*)mGroupPlusMenuHandle.get();
- if (!plus_menu)
- return;
-
- showGroupMenu(plus_menu);
+ return true;
}
void LLPanelPeople::onGroupMinusButtonClicked()
@@ -1288,10 +1188,6 @@ void LLPanelPeople::onFriendsViewSortMenuItemClicked(const LLSD& userdata)
mAllFriendList->showPermissions(show_permissions);
mOnlineFriendList->showPermissions(show_permissions);
}
- else if (chosen_item == "panel_block_list_sidetray")
- {
- LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD());
- }
}
void LLPanelPeople::onGroupsViewSortMenuItemClicked(const LLSD& userdata)
@@ -1324,10 +1220,6 @@ void LLPanelPeople::onNearbyViewSortMenuItemClicked(const LLSD& userdata)
{
setSortOrder(mNearbyList, E_SORT_BY_DISTANCE);
}
- else if (chosen_item == "panel_block_list_sidetray")
- {
- LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD());
- }
}
bool LLPanelPeople::onNearbyViewSortMenuItemCheck(const LLSD& userdata)
@@ -1361,10 +1253,6 @@ void LLPanelPeople::onRecentViewSortMenuItemClicked(const LLSD& userdata)
{
mRecentList->toggleIcons();
}
- else if (chosen_item == "panel_block_list_sidetray")
- {
- LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD());
- }
}
bool LLPanelPeople::onFriendsViewSortMenuItemCheck(const LLSD& userdata)
@@ -1393,40 +1281,6 @@ bool LLPanelPeople::onRecentViewSortMenuItemCheck(const LLSD& userdata)
return false;
}
-void LLPanelPeople::onCallButtonClicked()
-{
- uuid_vec_t selected_uuids;
- getCurrentItemIDs(selected_uuids);
-
- if (selected_uuids.size() == 1)
- {
- // initiate a P2P voice chat with the selected user
- LLAvatarActions::startCall(getCurrentItemID());
- }
- else if (selected_uuids.size() > 1)
- {
- // initiate an ad-hoc voice chat with multiple users
- LLAvatarActions::startAdhocCall(selected_uuids);
- }
-}
-
-void LLPanelPeople::onGroupCallButtonClicked()
-{
- LLGroupActions::startCall(getCurrentItemID());
-}
-
-void LLPanelPeople::onTeleportButtonClicked()
-{
- uuid_vec_t selected_uuids;
- getCurrentItemIDs(selected_uuids);
- LLAvatarActions::offerTeleport(selected_uuids);
-}
-
-void LLPanelPeople::onShareButtonClicked()
-{
- LLAvatarActions::share(getCurrentItemID());
-}
-
void LLPanelPeople::onMoreButtonClicked()
{
// *TODO: not implemented yet
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 46c58cd139..da27f83074 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -80,31 +80,22 @@ private:
std::string getActiveTabName() const;
LLUUID getCurrentItemID() const;
void getCurrentItemIDs(uuid_vec_t& selected_uuids) const;
- void buttonSetVisible(std::string btn_name, BOOL visible);
- void buttonSetEnabled(const std::string& btn_name, bool enabled);
- void buttonSetAction(const std::string& btn_name, const commit_signal_t::slot_type& cb);
void showGroupMenu(LLMenuGL* menu);
void setSortOrder(LLAvatarList* list, ESortOrder order, bool save = true);
// UI callbacks
void onFilterEdit(const std::string& search_string);
void onTabSelected(const LLSD& param);
- void onViewProfileButtonClicked();
void onAddFriendButtonClicked();
void onAddFriendWizButtonClicked();
void onDeleteFriendButtonClicked();
- void onGroupInfoButtonClicked();
void onChatButtonClicked();
+ void onGearButtonClicked(LLUICtrl* btn);
void onImButtonClicked();
- void onCallButtonClicked();
- void onGroupCallButtonClicked();
- void onTeleportButtonClicked();
- void onShareButtonClicked();
void onMoreButtonClicked();
- void onActivateButtonClicked();
void onAvatarListDoubleClicked(LLUICtrl* ctrl);
void onAvatarListCommitted(LLAvatarList* list);
- void onGroupPlusButtonClicked();
+ bool onGroupPlusButtonValidate();
void onGroupMinusButtonClicked();
void onGroupPlusMenuItemClicked(const LLSD& userdata);
@@ -113,8 +104,6 @@ private:
void onGroupsViewSortMenuItemClicked(const LLSD& userdata);
void onRecentViewSortMenuItemClicked(const LLSD& userdata);
- //returns false only if group is "none"
- bool isRealGroup();
bool onFriendsViewSortMenuItemCheck(const LLSD& userdata);
bool onRecentViewSortMenuItemCheck(const LLSD& userdata);
bool onNearbyViewSortMenuItemCheck(const LLSD& userdata);
@@ -135,7 +124,6 @@ private:
bool isAccordionCollapsedByUser(LLUICtrl* acc_tab);
bool isAccordionCollapsedByUser(const std::string& name);
- LLFilterEditor* mFilterEditor;
LLTabContainer* mTabContainer;
LLAvatarList* mOnlineFriendList;
LLAvatarList* mAllFriendList;
@@ -144,24 +132,13 @@ private:
LLGroupList* mGroupList;
LLNetMap* mMiniMap;
- LLHandle<LLView> mGroupPlusMenuHandle;
- LLHandle<LLView> mNearbyViewSortMenuHandle;
- LLHandle<LLView> mFriendsViewSortMenuHandle;
- LLHandle<LLView> mGroupsViewSortMenuHandle;
- LLHandle<LLView> mRecentViewSortMenuHandle;
+ std::vector<std::string> mSavedOriginalFilters;
+ std::vector<std::string> mSavedFilters;
Updater* mFriendListUpdater;
Updater* mNearbyListUpdater;
Updater* mRecentListUpdater;
Updater* mButtonsUpdater;
-
- LLMenuButton* mNearbyGearButton;
- LLMenuButton* mFriendsGearButton;
- LLMenuButton* mGroupsGearButton;
- LLMenuButton* mRecentGearButton;
-
- std::string mFilterSubString;
- std::string mFilterSubStringOrig;
};
#endif //LL_LLPANELPEOPLE_H
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 88727bf59b..29eb5ce69e 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -305,7 +305,11 @@ BOOL LLFloaterScriptSearch::handleKeyHere(KEY key, MASK mask)
{
if (mEditorCore)
{
- return mEditorCore->handleKeyHere(key, mask);
+ BOOL handled = mEditorCore->handleKeyHere(key, mask);
+ if (!handled)
+ {
+ LLFloater::handleKeyHere(key, mask);
+ }
}
return FALSE;
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index d340b304ca..003b53b28c 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -253,7 +253,14 @@ void LLScreenChannel::addToast(const LLToast::Params& p)
{
bool store_toast = false, show_toast = false;
- mDisplayToastsAlways ? show_toast = true : show_toast = mWasStartUpToastShown && (mShowToasts || p.force_show);
+ if (mDisplayToastsAlways)
+ {
+ show_toast = true;
+ }
+ else
+ {
+ show_toast = mWasStartUpToastShown && (mShowToasts || p.force_show);
+ }
store_toast = !show_toast && p.can_be_stored && mCanStoreToasts;
if(!show_toast && !store_toast)
@@ -371,7 +378,7 @@ void LLScreenChannel::storeToast(ToastElem& toast_elem)
const LLToast* toast = toast_elem.getToast();
if (toast)
{
- mStoredToastList.push_back(toast_elem);
+ mStoredToastList.push_back(toast_elem);
mOnStoreToast(toast->getPanel(), toast->getNotificationID());
}
}
@@ -410,14 +417,14 @@ void LLScreenChannel::loadStoredToastByNotificationIDToChannel(LLUUID id)
LLToast* toast = it->getToast();
if (toast)
{
- if(toast->getVisible())
- {
- // toast is already in channel
- return;
- }
+ if(toast->getVisible())
+ {
+ // toast is already in channel
+ return;
+ }
- toast->setIsHidden(false);
- toast->startTimer();
+ toast->setIsHidden(false);
+ toast->startTimer();
mToastList.push_back(*it);
}
@@ -444,7 +451,7 @@ void LLScreenChannel::removeStoredToastByNotificationID(LLUUID id)
it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
if (it != mStoredToastList.end())
{
- mStoredToastList.erase(it);
+ mStoredToastList.erase(it);
}
}
@@ -480,16 +487,16 @@ void LLScreenChannel::killToastByNotificationID(LLUUID id)
// searching among stored toasts
it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
- if (it != mStoredToastList.end())
+ if( it != mStoredToastList.end() )
{
LLToast* toast = it->getToast();
if (toast)
{
- // send signal to a listener to let him perform some action on toast rejecting
- mRejectToastSignal(toast->getNotificationID());
- deleteToast(toast);
- }
+ // send signal to a listener to let him perform some action on toast rejecting
+ mRejectToastSignal(toast->getNotificationID());
+ deleteToast(toast);
}
+}
// Call find() once more, because the mStoredToastList could have been changed
// in mRejectToastSignal callback and the iterator could have become invalid.
@@ -521,11 +528,11 @@ void LLScreenChannel::modifyToastByNotificationID(LLUUID id, LLPanel* panel)
LLToast* toast = it->getToast();
if (toast)
{
- LLPanel* old_panel = toast->getPanel();
- toast->removeChild(old_panel);
- delete old_panel;
- toast->insertPanel(panel);
- toast->startTimer();
+ LLPanel* old_panel = toast->getPanel();
+ toast->removeChild(old_panel);
+ delete old_panel;
+ toast->insertPanel(panel);
+ toast->startTimer();
}
redrawToasts();
}
@@ -679,7 +686,7 @@ void LLScreenChannel::showToastsCentre()
return;
}
- LLRect toast_rect;
+ LLRect toast_rect;
S32 bottom = (getRect().mTop - getRect().mBottom)/2 + toast->getRect().getHeight()/2;
std::vector<ToastElem>::reverse_iterator it;
diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h
index 56a9cf8b4b..eaff61a0f4 100644
--- a/indra/newview/llscreenchannel.h
+++ b/indra/newview/llscreenchannel.h
@@ -227,16 +227,16 @@ public:
// Channel's signals
// signal on storing of faded toasts event
- typedef boost::function<void (LLPanel* info_panel, const LLUUID id)> store_tost_callback_t;
- typedef boost::signals2::signal<void (LLPanel* info_panel, const LLUUID id)> store_tost_signal_t;
- store_tost_signal_t mOnStoreToast;
- boost::signals2::connection setOnStoreToastCallback(store_tost_callback_t cb) { return mOnStoreToast.connect(cb); }
+ typedef boost::signals2::signal<void (LLPanel* info_panel, const LLUUID id)> store_toast_signal_t;
+ boost::signals2::connection addOnStoreToastCallback(store_toast_signal_t::slot_type cb) { return mOnStoreToast.connect(cb); }
// signal on rejecting of a toast event
- typedef boost::function<void (LLUUID id)> reject_tost_callback_t;
- typedef boost::signals2::signal<void (LLUUID id)> reject_tost_signal_t;
- reject_tost_signal_t mRejectToastSignal; boost::signals2::connection setOnRejectToastCallback(reject_tost_callback_t cb) { return mRejectToastSignal.connect(cb); }
+ typedef boost::signals2::signal<void (LLUUID id)> reject_toast_signal_t;
+ boost::signals2::connection addOnRejectToastCallback(reject_toast_signal_t::slot_type cb) { return mRejectToastSignal.connect(cb); }
private:
+ store_toast_signal_t mOnStoreToast;
+ reject_toast_signal_t mRejectToastSignal;
+
class ToastElem
{
public:
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 5d196a465f..1333862855 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -2774,7 +2774,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
void renderCrossHairs(LLVector3 position, F32 size, LLColor4 color)
{
- gGL.diffuseColor4fv(color.mV);
+ gGL.color4fv(color.mV);
gGL.begin(LLRender::LINES);
{
gGL.vertex3fv((position - LLVector3(size, 0.f, 0.f)).mV);
@@ -3904,7 +3904,7 @@ void renderAgentTarget(LLVOAvatar* avatar)
if (avatar->isSelf())
{
renderCrossHairs(avatar->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f));
- renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f));
+ renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(0, 1, 0, 0.8f));
renderCrossHairs(avatar->mRoot.getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f));
renderCrossHairs(avatar->mPelvisp->getWorldPosition(), 0.2f, LLColor4(0, 0, 1, 0.8f));
}
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 0cb6c85012..18e0d9d0d2 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -433,13 +433,19 @@ BOOL LLIMWellWindow::ObjectRowPanel::handleRightMouseDown(S32 x, S32 y, MASK mas
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
+LLNotificationWellWindow::WellNotificationChannel::WellNotificationChannel(LLNotificationWellWindow* well_window)
+: LLNotificationChannel(LLNotificationChannel::Params().name(well_window->getPathname())),
+ mWellWindow(well_window)
+{
+ connectToChannel("Notifications");
+ connectToChannel("Group Notifications");
+ connectToChannel("Offer");
+}
+
LLNotificationWellWindow::LLNotificationWellWindow(const LLSD& key)
-: LLSysWellWindow(key)
+: LLSysWellWindow(key)
{
- // init connections to the list's update events
- connectListUpdaterToSignal("notify");
- connectListUpdaterToSignal("groupnotify");
- connectListUpdaterToSignal("offer");
+ mNotificationUpdates.reset(new WellNotificationChannel(this));
}
// static
@@ -519,7 +525,7 @@ void LLNotificationWellWindow::initChannel()
LLSysWellWindow::initChannel();
if(mChannel)
{
- mChannel->setOnStoreToastCallback(boost::bind(&LLNotificationWellWindow::onStoreToast, this, _1, _2));
+ mChannel->addOnStoreToastCallback(boost::bind(&LLNotificationWellWindow::onStoreToast, this, _1, _2));
}
}
@@ -546,20 +552,6 @@ void LLNotificationWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id)
addItem(p);
}
-void LLNotificationWellWindow::connectListUpdaterToSignal(std::string notification_type)
-{
- LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance();
- LLNotificationsUI::LLEventHandler* n_handler = manager->getHandlerForNotification(notification_type);
- if(n_handler)
- {
- n_handler->setNotificationIDCallback(boost::bind(&LLNotificationWellWindow::removeItemByID, this, _1));
- }
- else
- {
- llwarns << "LLSysWellWindow::connectListUpdaterToSignal() - could not get a handler for '" << notification_type <<"' type of notifications" << llendl;
- }
-}
-
void LLNotificationWellWindow::onItemClick(LLSysWellItem* item)
{
LLUUID id = item->getID();
@@ -574,6 +566,12 @@ void LLNotificationWellWindow::onItemClose(LLSysWellItem* item)
mChannel->killToastByNotificationID(id);
}
+void LLNotificationWellWindow::onAdd( LLNotificationPtr notify )
+{
+ removeItemByID(notify->getID());
+}
+
+
/************************************************************************/
@@ -867,4 +865,4 @@ bool LLIMWellWindow::confirmCloseAll(const LLSD& notification, const LLSD& respo
return false;
}
-// EOF
+
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index 272e9cfcb1..f497f546aa 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -34,6 +34,7 @@
#include "llscreenchannel.h"
#include "llscrollcontainer.h"
#include "llimview.h"
+#include "llnotifications.h"
#include "boost/shared_ptr.hpp"
@@ -111,7 +112,7 @@ public:
/*virtual*/ BOOL postBuild();
/*virtual*/ void setVisible(BOOL visible);
-
+ /*virtual*/ void onAdd(LLNotificationPtr notify);
// Operating with items
void addItem(LLSysWellItem::Params p);
@@ -119,6 +120,18 @@ public:
void closeAll();
protected:
+ struct WellNotificationChannel : public LLNotificationChannel
+ {
+ WellNotificationChannel(LLNotificationWellWindow*);
+ void onDelete(LLNotificationPtr notify)
+ {
+ mWellWindow->removeItemByID(notify->getID());
+ }
+
+ LLNotificationWellWindow* mWellWindow;
+ };
+
+ LLNotificationChannelPtr mNotificationUpdates;
/*virtual*/ const std::string& getAnchorViewName() { return NOTIFICATION_WELL_ANCHOR_NAME; }
private:
@@ -126,12 +139,8 @@ private:
void initChannel();
void clearScreenChannels();
-
void onStoreToast(LLPanel* info_panel, LLUUID id);
- // connect counter and list updaters to the corresponding signals
- void connectListUpdaterToSignal(std::string notification_type);
-
// Handlers
void onItemClick(LLSysWellItem* item);
void onItemClose(LLSysWellItem* item);
diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp
index 75178a6ef8..707d2d9765 100644
--- a/indra/newview/lltoastgroupnotifypanel.cpp
+++ b/indra/newview/lltoastgroupnotifypanel.cpp
@@ -51,7 +51,7 @@
const S32 LLToastGroupNotifyPanel::DEFAULT_MESSAGE_MAX_LINE_COUNT = 7;
-LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification)
+LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(const LLNotificationPtr& notification)
: LLToastPanel(notification),
mInventoryOffer(NULL)
{
diff --git a/indra/newview/lltoastgroupnotifypanel.h b/indra/newview/lltoastgroupnotifypanel.h
index 7794ec9f63..dfdc6ae559 100644
--- a/indra/newview/lltoastgroupnotifypanel.h
+++ b/indra/newview/lltoastgroupnotifypanel.h
@@ -47,13 +47,10 @@ class LLToastGroupNotifyPanel
public:
void close();
- static bool onNewNotification(const LLSD& notification);
-
-
// Non-transient messages. You can specify non-default button
// layouts (like one for script dialogs) by passing various
// numbers in for "layout".
- LLToastGroupNotifyPanel(LLNotificationPtr& notification);
+ LLToastGroupNotifyPanel(const LLNotificationPtr& notification);
/*virtual*/ ~LLToastGroupNotifyPanel();
protected:
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index de305bf3d9..dc5cc88dc4 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -52,7 +52,7 @@ const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL;
LLToastNotifyPanel::button_click_signal_t LLToastNotifyPanel::sButtonClickSignal;
-LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification, const LLRect& rect, bool show_images) :
+LLToastNotifyPanel::LLToastNotifyPanel(const LLNotificationPtr& notification, const LLRect& rect, bool show_images) :
LLToastPanel(notification),
mTextBox(NULL),
mInfoPanel(NULL),
@@ -536,7 +536,7 @@ void LLToastNotifyPanel::onToastPanelButtonClicked(const LLUUID& notification_id
}
}
-void LLToastNotifyPanel::disableRespondedOptions(LLNotificationPtr& notification)
+void LLToastNotifyPanel::disableRespondedOptions(const LLNotificationPtr& notification)
{
LLSD response = notification->getResponse();
for (LLSD::map_const_iterator response_it = response.beginMap();
diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h
index 57711b3d80..db517ec858 100644
--- a/indra/newview/lltoastnotifypanel.h
+++ b/indra/newview/lltoastnotifypanel.h
@@ -60,7 +60,7 @@ public:
* @deprecated if you intend to instantiate LLToastNotifyPanel - it's point to
* implement right class for desired toast panel. @see LLGenericTipPanel as example.
*/
- LLToastNotifyPanel(LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null, bool show_images = true);
+ LLToastNotifyPanel(const LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null, bool show_images = true);
virtual ~LLToastNotifyPanel();
LLPanel * getControlPanel() { return mControlPanel; }
@@ -118,7 +118,7 @@ protected:
/**
* Process response data. Will disable selected options
*/
- void disableRespondedOptions(LLNotificationPtr& notification);
+ void disableRespondedOptions(const LLNotificationPtr& notification);
bool mIsTip;
bool mAddedDefaultBtn;
diff --git a/indra/newview/lltoastscripttextbox.h b/indra/newview/lltoastscripttextbox.h
index 8e69d8834d..7d33446248 100644
--- a/indra/newview/lltoastscripttextbox.h
+++ b/indra/newview/lltoastscripttextbox.h
@@ -39,8 +39,6 @@ class LLToastScriptTextbox
public:
void close();
- static bool onNewNotification(const LLSD& notification);
-
// Non-transient messages. You can specify non-default button
// layouts (like one for script dialogs) by passing various
// numbers in for "layout".
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 7fdaac68c8..5ced32a9ab 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -110,6 +110,7 @@
#include "llfloatertranslationsettings.h"
#include "llfloateruipreview.h"
#include "llfloatervoiceeffect.h"
+#include "llfloatervoicevolume.h"
#include "llfloaterwhitelistentry.h"
#include "llfloaterwindowsize.h"
#include "llfloaterworldmap.h"
@@ -220,6 +221,7 @@ void LLViewerFloaterReg::registerFloaters()
LLInspectGroupUtil::registerFloater();
LLInspectObjectUtil::registerFloater();
LLInspectRemoteObjectUtil::registerFloater();
+ LLFloaterVoiceVolumeUtil::registerFloater();
LLNotificationsUI::registerFloater();
LLFloaterDisplayNameUtil::registerFloater();
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 12aed8f448..d75651835f 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -3190,15 +3190,6 @@ bool enable_freeze_eject(const LLSD& avatar_id)
return new_value;
}
-
-void login_done(S32 which, void *user)
-{
- llinfos << "Login done " << which << llendl;
-
- LLPanelLogin::closePanel();
-}
-
-
bool callback_leave_group(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 2917fee62e..c2bafd043d 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1148,7 +1148,7 @@ bool check_offer_throttle(const std::string& from_name, bool check_only)
}
}
}
-
+
// Return "true" if we have a preview method for that asset type, "false" otherwise
bool check_asset_previewable(const LLAssetType::EType asset_type)
{
@@ -2373,7 +2373,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
bool mute_im = is_muted;
- if (accept_im_from_only_friend && !is_friend)
+ if(accept_im_from_only_friend&&!is_friend)
{
if (!gIMMgr->isNonFriendSessionNotified(session_id))
{
@@ -2796,7 +2796,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
chat.mOwnerID = from_id;
LLSD args;
args["slurl"] = location;
- args["type"] = LLNotificationsUI::NT_NEARBYCHAT;
// Look for IRC-style emotes here so object name formatting is correct
std::string prefix = message.substr(0, 4);
@@ -3399,7 +3398,6 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
// pass owner_id to chat so that we can display the remote
// object inspect for an object that is chatting with you
LLSD args;
- args["type"] = LLNotificationsUI::NT_NEARBYCHAT;
chat.mOwnerID = owner_id;
if (gSavedSettings.getBOOL("TranslateChat") && chat.mSourceType != CHAT_SOURCE_SYSTEM)
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 589714c25c..117078bcd1 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -610,7 +610,7 @@ public:
addText(xpos, ypos, llformat("%d/%d Mesh HTTP Requests/Retries", LLMeshRepository::sHTTPRequestCount,
LLMeshRepository::sHTTPRetryCount));
ypos += y_inc;
-
+
addText(xpos, ypos, llformat("%d/%d Mesh LOD Pending/Processing", LLMeshRepository::sLODPending, LLMeshRepository::sLODProcessing));
ypos += y_inc;
@@ -1542,13 +1542,14 @@ LLViewerWindow::LLViewerWindow(const Params& p)
// pass its value right now. Instead, pass it a nullary function that
// will, when we later need it, return the value of gKeyboard.
// boost::lambda::var() constructs such a functor on the fly.
- mWindowListener.reset(new LLWindowListener(this, boost::lambda::var(gKeyboard)));
- mViewerWindowListener.reset(new LLViewerWindowListener(this));
- LLNotificationChannel::buildChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert"));
- LLNotificationChannel::buildChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal"));
+ mWindowListener(new LLWindowListener(this, boost::lambda::var(gKeyboard))),
+ mViewerWindowListener(new LLViewerWindowListener(this)),
- LLNotifications::instance().getChannel("VW_alerts")->connectChanged(&LLViewerWindow::onAlert);
- LLNotifications::instance().getChannel("VW_alertmodal")->connectChanged(&LLViewerWindow::onAlert);
+ LLNotificationChannelPtr vw_alerts_channel(new LLNotificationChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert")));
+ LLNotificationChannelPtr vw_alerts_modal_channel(new LLNotificationChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal")));
+
+ vw_alerts_channel->connectChanged(&LLViewerWindow::onAlert);
+ vw_alerts_modal_channel->connectChanged(&LLViewerWindow::onAlert);
LLNotifications::instance().setIgnoreAllNotifications(gSavedSettings.getBOOL("IgnoreAllNotifications"));
llinfos << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << llendl;
@@ -1969,12 +1970,12 @@ void LLViewerWindow::shutdownViews()
gMorphView->setVisible(FALSE);
}
llinfos << "Global views cleaned." << llendl ;
-
+
// DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open
// will crump with LL_ERRS.
LLModalDialog::shutdownModals();
llinfos << "LLModalDialog shut down." << llendl;
-
+
// destroy the nav bar, not currently part of gViewerWindow
// *TODO: Make LLNavigationBar part of gViewerWindow
if (LLNavigationBar::instanceExists())
@@ -1982,17 +1983,17 @@ void LLViewerWindow::shutdownViews()
delete LLNavigationBar::getInstance();
}
llinfos << "LLNavigationBar destroyed." << llendl ;
-
+
// destroy menus after instantiating navbar above, as it needs
// access to gMenuHolder
cleanup_menus();
llinfos << "menus destroyed." << llendl ;
-
+
// Delete all child views.
delete mRootView;
mRootView = NULL;
llinfos << "RootView deleted." << llendl ;
-
+
// Automatically deleted as children of mRootView. Fix the globals.
gStatusBar = NULL;
gIMMgr = NULL;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index bc7f5a9744..e1d29da664 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -62,6 +62,7 @@
#include "llhudmanager.h"
#include "llhudnametag.h"
#include "llhudtext.h" // for mText/mDebugText
+#include "llinitparam.h"
#include "llkeyframefallmotion.h"
#include "llkeyframestandmotion.h"
#include "llkeyframewalkmotion.h"
@@ -193,6 +194,9 @@ const S32 MAX_BUBBLE_CHAT_LENGTH = DB_CHAT_MSG_STR_LEN;
const S32 MAX_BUBBLE_CHAT_UTTERANCES = 12;
const F32 CHAT_FADE_TIME = 8.0;
const F32 BUBBLE_CHAT_TIME = CHAT_FADE_TIME * 3.f;
+const F32 NAMETAG_UPDATE_THRESHOLD = 0.3f;
+const F32 NAMETAG_VERTICAL_SCREEN_OFFSET = 25.f;
+const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.17f;
const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0);
@@ -224,55 +228,62 @@ struct LLTextureMaskData
**/
//------------------------------------------------------------------------
-// LLVOBoneInfo
+// LLVOAvatarBoneInfo
// Trans/Scale/Rot etc. info about each avatar bone. Used by LLVOAvatarSkeleton.
//------------------------------------------------------------------------
-class LLVOAvatarBoneInfo
+struct LLVOAvatarCollisionVolumeInfo : public LLInitParam::Block<LLVOAvatarCollisionVolumeInfo>
{
- friend class LLVOAvatar;
- friend class LLVOAvatarSkeletonInfo;
-public:
- LLVOAvatarBoneInfo() : mIsJoint(FALSE) {}
- ~LLVOAvatarBoneInfo()
- {
- std::for_each(mChildList.begin(), mChildList.end(), DeletePointer());
- }
- BOOL parseXml(LLXmlTreeNode* node);
+ LLVOAvatarCollisionVolumeInfo()
+ : name("name"),
+ pos("pos"),
+ rot("rot"),
+ scale("scale")
+ {}
+
+ Mandatory<std::string> name;
+ Mandatory<LLVector3> pos,
+ rot,
+ scale;
+};
+
+struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoint>
+{
+ Alternative<Lazy<struct LLVOAvatarBoneInfo, IS_A_BLOCK> > bone;
+ Alternative<LLVOAvatarCollisionVolumeInfo> collision_volume;
+
+ LLVOAvatarChildJoint()
+ : bone("bone"),
+ collision_volume("collision_volume")
+ {}
+};
+
+struct LLVOAvatarBoneInfo : public LLInitParam::Block<LLVOAvatarBoneInfo, LLVOAvatarCollisionVolumeInfo>
+{
+ LLVOAvatarBoneInfo()
+ : pivot("pivot")
+ {}
-private:
- std::string mName;
- BOOL mIsJoint;
- LLVector3 mPos;
- LLVector3 mRot;
- LLVector3 mScale;
- LLVector3 mPivot;
- typedef std::vector<LLVOAvatarBoneInfo*> child_list_t;
- child_list_t mChildList;
+ Mandatory<LLVector3> pivot;
+ Multiple<LLVOAvatarChildJoint> children;
};
//------------------------------------------------------------------------
// LLVOAvatarSkeletonInfo
// Overall avatar skeleton
//------------------------------------------------------------------------
-class LLVOAvatarSkeletonInfo
+struct LLVOAvatarSkeletonInfo : public LLInitParam::Block<LLVOAvatarSkeletonInfo>
{
- friend class LLVOAvatar;
-public:
- LLVOAvatarSkeletonInfo() :
- mNumBones(0), mNumCollisionVolumes(0) {}
- ~LLVOAvatarSkeletonInfo()
- {
- std::for_each(mBoneInfoList.begin(), mBoneInfoList.end(), DeletePointer());
- }
- BOOL parseXml(LLXmlTreeNode* node);
- S32 getNumBones() const { return mNumBones; }
- S32 getNumCollisionVolumes() const { return mNumCollisionVolumes; }
+ LLVOAvatarSkeletonInfo()
+ : skeleton_root(""),
+ num_bones("num_bones"),
+ num_collision_volumes("num_collision_volumes"),
+ version("version")
+ {}
-private:
- S32 mNumBones;
- S32 mNumCollisionVolumes;
- typedef std::vector<LLVOAvatarBoneInfo*> bone_info_list_t;
- bone_info_list_t mBoneInfoList;
+ Mandatory<std::string> version;
+ Mandatory<S32> num_bones,
+ num_collision_volumes;
+ Mandatory<LLVOAvatarChildJoint> skeleton_root;
};
//-----------------------------------------------------------------------------
@@ -597,7 +608,7 @@ private:
// Static Data
//-----------------------------------------------------------------------------
LLXmlTree LLVOAvatar::sXMLTree;
-LLXmlTree LLVOAvatar::sSkeletonXMLTree;
+LLXMLNodePtr LLVOAvatar::sSkeletonXMLTree;
LLVOAvatarSkeletonInfo* LLVOAvatar::sAvatarSkeletonInfo = NULL;
LLVOAvatar::LLVOAvatarXmlInfo* LLVOAvatar::sAvatarXmlInfo = NULL;
LLVOAvatarDictionary *LLVOAvatar::sAvatarDictionary = NULL;
@@ -698,9 +709,13 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
LLMemType mt(LLMemType::MTYPE_AVATAR);
//VTResume(); // VTune
+#ifdef XXX_STINSON_CHUI_REWORK
// mVoiceVisualizer is created by the hud effects manager and uses the HUD Effects pipeline
const BOOL needsSendToSim = false; // currently, this HUD effect doesn't need to pack and unpack data to do its job
mVoiceVisualizer = ( LLVoiceVisualizer *)LLHUDManager::getInstance()->createViewerEffect( LLHUDObject::LL_HUD_EFFECT_VOICE_VISUALIZER, needsSendToSim );
+#else // XXX_STINSON_CHUI_REWORK
+ mVoiceVisualizer = new LLVoiceVisualizer();
+#endif // XXX_STINSON_CHUI_REWORK
lldebugs << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << llendl;
@@ -859,7 +874,11 @@ void LLVOAvatar::markDead()
mNameText = NULL;
sNumVisibleChatBubbles--;
}
+#ifdef XXX_STINSON_CHUI_REWORK
mVoiceVisualizer->markDead();
+#else // XXX_STINSON_CHUI_REWORK
+ mVoiceVisualizer->setStopSpeaking();
+#endif // XXX_STINSON_CHUI_REWORK
LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ;
LLViewerObject::markDead();
}
@@ -1123,18 +1142,6 @@ void LLVOAvatar::initClass()
llerrs << "Error parsing skeleton file: " << skeleton_path << llendl;
}
- // Process XML data
-
- // avatar_skeleton.xml
- if (sAvatarSkeletonInfo)
- { //this can happen if a login attempt failed
- delete sAvatarSkeletonInfo;
- }
- sAvatarSkeletonInfo = new LLVOAvatarSkeletonInfo;
- if (!sAvatarSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot()))
- {
- llerrs << "Error parsing skeleton XML file: " << skeleton_path << llendl;
- }
// parse avatar_lad.xml
if (sAvatarXmlInfo)
{ //this can happen if a login attempt failed
@@ -1183,7 +1190,7 @@ void LLVOAvatar::initClass()
void LLVOAvatar::cleanupClass()
{
deleteAndClear(sAvatarXmlInfo);
- sSkeletonXMLTree.cleanup();
+ sSkeletonXMLTree = NULL;
sXMLTree.cleanup();
}
@@ -1329,7 +1336,9 @@ void LLVOAvatar::initInstance(void)
//VTPause(); // VTune
+#ifdef XXX_STINSON_CHUI_REWORK
mVoiceVisualizer->setVoiceEnabled( LLVoiceClient::getInstance()->getVoiceEnabled( mID ) );
+#endif // XXX_STINSON_CHUI_REWORK
}
@@ -1655,33 +1664,39 @@ BOOL LLVOAvatar::parseSkeletonFile(const std::string& filename)
//-------------------------------------------------------------------------
// parse the file
//-------------------------------------------------------------------------
- BOOL parsesuccess = sSkeletonXMLTree.parseFile( filename, FALSE );
+
+ LLXMLNodePtr skeleton_xml;
+ BOOL parsesuccess = LLXMLNode::parseFile(filename, skeleton_xml, NULL);
- if (!parsesuccess)
+ if (!parsesuccess || skeleton_xml.isNull())
{
llerrs << "Can't parse skeleton file: " << filename << llendl;
return FALSE;
}
- // now sanity check xml file
- LLXmlTreeNode* root = sSkeletonXMLTree.getRoot();
- if (!root)
+ // Process XML data
+ if (sAvatarSkeletonInfo)
+ { //this can happen if a login attempt failed
+ delete sAvatarSkeletonInfo;
+ }
+ sAvatarSkeletonInfo = new LLVOAvatarSkeletonInfo;
+
+ LLXUIParser parser;
+ parser.readXUI(skeleton_xml, *sAvatarSkeletonInfo, filename);
+ if (!sAvatarSkeletonInfo->validateBlock())
{
- llerrs << "No root node found in avatar skeleton file: " << filename << llendl;
- return FALSE;
+ llerrs << "Error parsing skeleton XML file: " << filename << llendl;
}
- if( !root->hasName( "linden_skeleton" ) )
+ if( !skeleton_xml->hasName( "linden_skeleton" ) )
{
llerrs << "Invalid avatar skeleton file header: " << filename << llendl;
return FALSE;
}
- std::string version;
- static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
- if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
+ if (sAvatarSkeletonInfo->version() != "1.0")
{
- llerrs << "Invalid avatar skeleton file version: " << version << " in file: " << filename << llendl;
+ llerrs << "Invalid avatar skeleton file version: " << sAvatarSkeletonInfo->version() << " in file: " << filename << llendl;
return FALSE;
}
@@ -1690,14 +1705,13 @@ BOOL LLVOAvatar::parseSkeletonFile(const std::string& filename)
//-----------------------------------------------------------------------------
// setupBone()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 &volume_num, S32 &joint_num)
+//-----------------------------------------------------------
+BOOL LLVOAvatar::setupBone(const LLVOAvatarChildJoint& info, LLViewerJoint* parent, S32 &volume_num, S32 &joint_num)
{
LLMemType mt(LLMemType::MTYPE_AVATAR);
LLViewerJoint* joint = NULL;
-
- if (info->mIsJoint)
+ if (info.bone.isChosen())
{
joint = (LLViewerJoint*)getCharacterJoint(joint_num);
if (!joint)
@@ -1705,7 +1719,23 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent
llwarns << "Too many bones" << llendl;
return FALSE;
}
- joint->setName( info->mName );
+ joint->setName( info.bone().name );
+ joint->setPosition(info.bone().pos);
+ joint->setRotation(mayaQ(info.bone().rot().mV[VX], info.bone().rot().mV[VY], info.bone().rot().mV[VZ], LLQuaternion::XYZ));
+ joint->setScale(info.bone().scale);
+ joint->setSkinOffset( info.bone().pivot );
+ joint_num++;
+
+ for (LLInitParam::ParamIterator<LLVOAvatarChildJoint>::const_iterator child_it = info.bone().children.begin(),
+ end_it = info.bone().children.end();
+ child_it != end_it;
+ ++child_it)
+ {
+ if (!setupBone(*child_it, joint, volume_num, joint_num))
+ {
+ return FALSE;
+ }
+ }
}
else // collision volume
{
@@ -1715,7 +1745,11 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent
return FALSE;
}
joint = (LLViewerJoint*)(&mCollisionVolumes[volume_num]);
- joint->setName( info->mName );
+ joint->setName( info.collision_volume.name);
+ joint->setPosition(info.collision_volume.pos);
+ joint->setRotation(mayaQ(info.collision_volume.rot().mV[VX], info.collision_volume.rot().mV[VY], info.collision_volume.rot().mV[VZ], LLQuaternion::XYZ));
+ joint->setScale(info.collision_volume.scale);
+ volume_num++;
}
// add to parent
@@ -1724,34 +1758,8 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent
parent->addChild( joint );
}
- joint->setPosition(info->mPos);
- joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY],
- info->mRot.mV[VZ], LLQuaternion::XYZ));
- joint->setScale(info->mScale);
-
joint->setDefaultFromCurrentXform();
- if (info->mIsJoint)
- {
- joint->setSkinOffset( info->mPivot );
- joint_num++;
- }
- else // collision volume
- {
- volume_num++;
- }
-
- // setup children
- LLVOAvatarBoneInfo::child_list_t::const_iterator iter;
- for (iter = info->mChildList.begin(); iter != info->mChildList.end(); ++iter)
- {
- LLVOAvatarBoneInfo *child_info = *iter;
- if (!setupBone(child_info, joint, volume_num, joint_num))
- {
- return FALSE;
- }
- }
-
return TRUE;
}
@@ -1765,35 +1773,31 @@ BOOL LLVOAvatar::buildSkeleton(const LLVOAvatarSkeletonInfo *info)
//-------------------------------------------------------------------------
// allocate joints
//-------------------------------------------------------------------------
- if (!allocateCharacterJoints(info->mNumBones))
+ if (!allocateCharacterJoints(info->num_bones))
{
- llerrs << "Can't allocate " << info->mNumBones << " joints" << llendl;
+ llerrs << "Can't allocate " << info->num_bones() << " joints" << llendl;
return FALSE;
}
//-------------------------------------------------------------------------
// allocate volumes
//-------------------------------------------------------------------------
- if (info->mNumCollisionVolumes)
+ if (info->num_collision_volumes)
{
- if (!allocateCollisionVolumes(info->mNumCollisionVolumes))
+ if (!allocateCollisionVolumes(info->num_collision_volumes))
{
- llerrs << "Can't allocate " << info->mNumCollisionVolumes << " collision volumes" << llendl;
+ llerrs << "Can't allocate " << info->num_collision_volumes() << " collision volumes" << llendl;
return FALSE;
}
}
S32 current_joint_num = 0;
S32 current_volume_num = 0;
- LLVOAvatarSkeletonInfo::bone_info_list_t::const_iterator iter;
- for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); ++iter)
+
+ if (!setupBone(info->skeleton_root, NULL, current_volume_num, current_joint_num))
{
- LLVOAvatarBoneInfo *info = *iter;
- if (!setupBone(info, NULL, current_volume_num, current_joint_num))
- {
- llerrs << "Error parsing bone in skeleton file" << llendl;
- return FALSE;
- }
+ llerrs << "Error parsing bone in skeleton file" << llendl;
+ return FALSE;
}
return TRUE;
@@ -2430,6 +2434,7 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
{
+#ifdef XXX_STINSON_CHUI_REWORK
bool render_visualizer = voice_enabled;
// Don't render the user's own voice visualizer when in mouselook, or when opening the mic is disabled.
@@ -2442,6 +2447,7 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
}
mVoiceVisualizer->setVoiceEnabled(render_visualizer);
+#endif // XXX_STINSON_CHUI_REWORK
if ( voice_enabled )
{
@@ -2517,6 +2523,7 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
}
}
+#ifdef XXX_STINSON_CHUI_REWORK
//--------------------------------------------------------------------------------------------
// here we get the approximate head position and set as sound source for the voice symbol
// (the following version uses a tweak of "mHeadOffset" which handle sitting vs. standing)
@@ -2534,6 +2541,7 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
tagPos[VZ] += ( mBodySize[VZ] + 0.125f );
mVoiceVisualizer->setVoiceSourceWorldPosition( tagPos );
}
+#endif // XXX_STINSON_CHUI_REWORK
}//if ( voiceEnabled )
}
@@ -2922,43 +2930,43 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
return;
}
- BOOL new_name = FALSE;
- if (visible_chat != mVisibleChat)
- {
- mVisibleChat = visible_chat;
- new_name = TRUE;
- }
+ BOOL new_name = FALSE;
+ if (visible_chat != mVisibleChat)
+ {
+ mVisibleChat = visible_chat;
+ new_name = TRUE;
+ }
- if (sRenderGroupTitles != mRenderGroupTitles)
- {
- mRenderGroupTitles = sRenderGroupTitles;
- new_name = TRUE;
- }
+ if (sRenderGroupTitles != mRenderGroupTitles)
+ {
+ mRenderGroupTitles = sRenderGroupTitles;
+ new_name = TRUE;
+ }
- // First Calculate Alpha
- // If alpha > 0, create mNameText if necessary, otherwise delete it
- F32 alpha = 0.f;
- if (mAppAngle > 5.f)
+ // First Calculate Alpha
+ // If alpha > 0, create mNameText if necessary, otherwise delete it
+ F32 alpha = 0.f;
+ if (mAppAngle > 5.f)
+ {
+ const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION;
+ if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME)
{
- const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION;
- if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME)
- {
- alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION;
- }
- else
- {
- // ...not fading, full alpha
- alpha = 1.f;
- }
+ alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION;
}
- else if (mAppAngle > 2.f)
+ else
{
- // far away is faded out also
- alpha = (mAppAngle-2.f)/3.f;
+ // ...not fading, full alpha
+ alpha = 1.f;
}
+ }
+ else if (mAppAngle > 2.f)
+ {
+ // far away is faded out also
+ alpha = (mAppAngle-2.f)/3.f;
+ }
if (alpha <= 0.f)
- {
+ {
if (mNameText)
{
mNameText->markDead();
@@ -2968,31 +2976,30 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
return;
}
- if (!mNameText)
- {
+ if (!mNameText)
+ {
mNameText = static_cast<LLHUDNameTag*>( LLHUDObject::addHUDObject(
LLHUDObject::LL_HUD_NAME_TAG) );
//mNameText->setMass(10.f);
- mNameText->setSourceObject(this);
+ mNameText->setSourceObject(this);
mNameText->setVertAlignment(LLHUDNameTag::ALIGN_VERT_TOP);
- mNameText->setVisibleOffScreen(TRUE);
- mNameText->setMaxLines(11);
- mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
- sNumVisibleChatBubbles++;
- new_name = TRUE;
- }
+ mNameText->setVisibleOffScreen(TRUE);
+ mNameText->setMaxLines(11);
+ mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
+ sNumVisibleChatBubbles++;
+ new_name = TRUE;
+ }
- LLVector3 name_position = idleUpdateNameTagPosition(root_pos_last);
- mNameText->setPositionAgent(name_position);
+ idleUpdateNameTagPosition(root_pos_last);
idleUpdateNameTagText(new_name);
idleUpdateNameTagAlpha(new_name, alpha);
}
void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
- {
- LLNameValue *title = getNVPair("Title");
- LLNameValue* firstname = getNVPair("FirstName");
- LLNameValue* lastname = getNVPair("LastName");
+{
+ LLNameValue *title = getNVPair("Title");
+ LLNameValue* firstname = getNVPair("FirstName");
+ LLNameValue* lastname = getNVPair("LastName");
// Avatars must have a first and last name
if (!firstname || !lastname) return;
@@ -3006,34 +3013,29 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
is_muted = false;
}
else
- {
+ {
is_muted = LLMuteList::getInstance()->isMuted(getID());
}
bool is_friend = LLAvatarTracker::instance().isBuddy(getID());
bool is_cloud = getIsCloud();
- if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
- {
- if (is_appearance != mNameAppearance)
- {
- if (is_appearance)
- {
- LLSD args;
- args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
- args["NAME"] = getFullname();
- LLNotificationsUtil::add("AvatarRezEnteredAppearanceNotification",args);
- llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' entered appearance mode." << llendl;
- }
- else
- {
- LLSD args;
- args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
- args["NAME"] = getFullname();
- LLNotificationsUtil::add("AvatarRezLeftAppearanceNotification",args);
- llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left appearance mode." << llendl;
- }
- }
- }
+ if (gSavedSettings.getBOOL("DebugAvatarRezTime")
+ && is_appearance != mNameAppearance)
+ {
+ LLSD args;
+ args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
+ args["NAME"] = getFullname();
+ if (is_appearance)
+ {
+ LLNotificationsUtil::add("AvatarRezEnteredAppearanceNotification",args);
+ llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' entered appearance mode." << llendl;
+ }
+ else
+ {
+ LLNotificationsUtil::add("AvatarRezLeftAppearanceNotification",args);
+ llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left appearance mode." << llendl;
+ }
+ }
// Rebuild name tag if state change detected
if (mNameString.empty()
@@ -3043,39 +3045,39 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
|| is_away != mNameAway
|| is_busy != mNameBusy
|| is_muted != mNameMute
- || is_appearance != mNameAppearance
+ || is_appearance != mNameAppearance
|| is_friend != mNameFriend
|| is_cloud != mNameCloud)
- {
+ {
LLColor4 name_tag_color = getNameTagColor(is_friend);
clearNameTag();
if (is_away || is_muted || is_busy || is_appearance)
- {
+ {
std::string line;
- if (is_away)
- {
- line += LLTrans::getString("AvatarAway");
+ if (is_away)
+ {
+ line += LLTrans::getString("AvatarAway");
line += ", ";
- }
- if (is_busy)
- {
+ }
+ if (is_busy)
+ {
line += LLTrans::getString("AvatarBusy");
line += ", ";
}
if (is_muted)
- {
+ {
line += LLTrans::getString("AvatarMuted");
- line += ", ";
- }
+ line += ", ";
+ }
if (is_appearance)
{
line += LLTrans::getString("AvatarEditingAppearance");
line += ", ";
- }
+ }
if (is_cloud)
- {
+ {
line += LLTrans::getString("LoadingData");
line += ", ";
}
@@ -3087,12 +3089,12 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
if (sRenderGroupTitles
&& title && title->getString() && title->getString()[0] != '\0')
- {
+ {
std::string title_str = title->getString();
LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR);
addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL,
LLFontGL::getFontSansSerifSmall());
- }
+ }
static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames");
static LLUICachedControl<bool> show_usernames("NameTagShowUsernames");
@@ -3106,119 +3108,118 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
// and force a rebuild
LLAvatarNameCache::get(getID(),
boost::bind(&LLVOAvatar::clearNameTag, this));
- }
+ }
// Might be blank if name not available yet, that's OK
if (show_display_names)
{
addNameTagLine(av_name.mDisplayName, name_tag_color, LLFontGL::NORMAL,
LLFontGL::getFontSansSerif());
- }
+ }
// Suppress SLID display if display name matches exactly (ugh)
if (show_usernames && !av_name.mIsDisplayNameDefault)
- {
+ {
// *HACK: Desaturate the color
LLColor4 username_color = name_tag_color * 0.83f;
addNameTagLine(av_name.mUsername, username_color, LLFontGL::NORMAL,
LLFontGL::getFontSansSerifSmall());
}
- }
+ }
else
- {
+ {
const LLFontGL* font = LLFontGL::getFontSansSerif();
- std::string full_name =
- LLCacheName::buildFullName( firstname->getString(), lastname->getString() );
+ std::string full_name = LLCacheName::buildFullName( firstname->getString(), lastname->getString() );
addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font);
- }
+ }
- mNameAway = is_away;
- mNameBusy = is_busy;
- mNameMute = is_muted;
- mNameAppearance = is_appearance;
- mNameFriend = is_friend;
- mNameCloud = is_cloud;
- mTitle = title ? title->getString() : "";
- LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR);
- new_name = TRUE;
- }
+ mNameAway = is_away;
+ mNameBusy = is_busy;
+ mNameMute = is_muted;
+ mNameAppearance = is_appearance;
+ mNameFriend = is_friend;
+ mNameCloud = is_cloud;
+ mTitle = title ? title->getString() : "";
+ LLStringFn::replace_ascii_controlchars(mTitle, LL_UNKNOWN_CHAR);
+ new_name = TRUE;
+ }
if (mVisibleChat)
- {
- mNameText->setFont(LLFontGL::getFontSansSerif());
+ {
+ mNameText->setFont(LLFontGL::getFontSansSerif());
mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT);
- mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f);
-
- char line[MAX_STRING]; /* Flawfinder: ignore */
- line[0] = '\0';
- std::deque<LLChat>::iterator chat_iter = mChats.begin();
- mNameText->clearString();
-
- LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" );
- LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f);
- LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f);
- if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES)
- {
- ++chat_iter;
- }
+ mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f);
- for(; chat_iter != mChats.end(); ++chat_iter)
- {
- F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f);
- LLFontGL::StyleFlags style;
- switch(chat_iter->mChatType)
- {
- case CHAT_TYPE_WHISPER:
- style = LLFontGL::ITALIC;
- break;
- case CHAT_TYPE_SHOUT:
- style = LLFontGL::BOLD;
- break;
- default:
- style = LLFontGL::NORMAL;
- break;
- }
- if (chat_fade_amt < 1.f)
- {
- F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f);
- mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style);
- }
- else if (chat_fade_amt < 2.f)
- {
- F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f);
- mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style);
- }
- else if (chat_fade_amt < 3.f)
- {
- // *NOTE: only remove lines down to minimum number
- mNameText->addLine(chat_iter->mText, old_chat, style);
- }
- }
- mNameText->setVisibleOffScreen(TRUE);
+ char line[MAX_STRING]; /* Flawfinder: ignore */
+ line[0] = '\0';
+ std::deque<LLChat>::iterator chat_iter = mChats.begin();
+ mNameText->clearString();
- if (mTyping)
- {
- S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1;
- switch(dot_count)
- {
- case 1:
- mNameText->addLine(".", new_chat);
- break;
- case 2:
- mNameText->addLine("..", new_chat);
- break;
- case 3:
- mNameText->addLine("...", new_chat);
- break;
- }
+ LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" );
+ LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f);
+ LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f);
+ if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES)
+ {
+ ++chat_iter;
+ }
- }
+ for(; chat_iter != mChats.end(); ++chat_iter)
+ {
+ F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f);
+ LLFontGL::StyleFlags style;
+ switch(chat_iter->mChatType)
+ {
+ case CHAT_TYPE_WHISPER:
+ style = LLFontGL::ITALIC;
+ break;
+ case CHAT_TYPE_SHOUT:
+ style = LLFontGL::BOLD;
+ break;
+ default:
+ style = LLFontGL::NORMAL;
+ break;
}
- else
+ if (chat_fade_amt < 1.f)
{
+ F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f);
+ mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style);
+ }
+ else if (chat_fade_amt < 2.f)
+ {
+ F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f);
+ mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style);
+ }
+ else if (chat_fade_amt < 3.f)
+ {
+ // *NOTE: only remove lines down to minimum number
+ mNameText->addLine(chat_iter->mText, old_chat, style);
+ }
+ }
+ mNameText->setVisibleOffScreen(TRUE);
+
+ if (mTyping)
+ {
+ S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1;
+ switch(dot_count)
+ {
+ case 1:
+ mNameText->addLine(".", new_chat);
+ break;
+ case 2:
+ mNameText->addLine("..", new_chat);
+ break;
+ case 3:
+ mNameText->addLine("...", new_chat);
+ break;
+ }
+
+ }
+ }
+ else
+ {
// ...not using chat bubbles, just names
mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_CENTER);
- mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
- mNameText->setVisibleOffScreen(FALSE);
+ mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
+ mNameText->setVisibleOffScreen(FALSE);
}
}
@@ -3241,8 +3242,8 @@ void LLVOAvatar::clearNameTag()
{
mNameString.clear();
if (mNameText)
- {
- mNameText->setLabel("");
+ {
+ mNameText->setLabel("");
mNameText->setString( "" );
}
}
@@ -3270,34 +3271,45 @@ void LLVOAvatar::invalidateNameTags()
if (avatar->isDead()) continue;
avatar->clearNameTag();
-
}
}
// Compute name tag position during idle update
-LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
+void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
{
LLQuaternion root_rot = mRoot.getWorldRotation();
+ LLQuaternion inv_root_rot = ~root_rot;
LLVector3 pixel_right_vec;
LLVector3 pixel_up_vec;
LLViewerCamera::getInstance()->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec);
LLVector3 camera_to_av = root_pos_last - LLViewerCamera::getInstance()->getOrigin();
camera_to_av.normalize();
- LLVector3 local_camera_at = camera_to_av * ~root_rot;
+ LLVector3 local_camera_at = camera_to_av * inv_root_rot;
LLVector3 local_camera_up = camera_to_av % LLViewerCamera::getInstance()->getLeftAxis();
local_camera_up.normalize();
- local_camera_up = local_camera_up * ~root_rot;
+ local_camera_up = local_camera_up * inv_root_rot;
+
+ LLVector3 avatar_ellipsoid(mBodySize.mV[VX] * 0.4f,
+ mBodySize.mV[VY] * 0.4f,
+ mBodySize.mV[VZ] * NAMETAG_VERT_OFFSET_WEIGHT);
- local_camera_up.scaleVec(mBodySize * 0.5f);
- local_camera_at.scaleVec(mBodySize * 0.5f);
+ local_camera_up.scaleVec(avatar_ellipsoid);
+ local_camera_at.scaleVec(avatar_ellipsoid);
- LLVector3 name_position = mRoot.getWorldPosition();
- name_position[VZ] -= mPelvisToFoot;
- name_position[VZ] += (mBodySize[VZ]* 0.55f);
+ LLVector3 head_offset = (mHeadp->getLastWorldPosition() - mRoot.getLastWorldPosition()) * inv_root_rot;
+
+ if (dist_vec(head_offset, mTargetRootToHeadOffset) > NAMETAG_UPDATE_THRESHOLD)
+ {
+ mTargetRootToHeadOffset = head_offset;
+ }
+
+ mCurRootToHeadOffset = lerp(mCurRootToHeadOffset, mTargetRootToHeadOffset, LLCriticalDamp::getInterpolant(0.2f));
+
+ LLVector3 name_position = mRoot.getLastWorldPosition() + (mCurRootToHeadOffset * root_rot);
name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av));
- name_position += pixel_up_vec * 15.f;
+ name_position += pixel_up_vec * NAMETAG_VERTICAL_SCREEN_OFFSET;
- return name_position;
+ mNameText->setPositionAgent(name_position);
}
void LLVOAvatar::idleUpdateNameTagAlpha(BOOL new_name, F32 alpha)
@@ -3333,7 +3345,7 @@ LLColor4 LLVOAvatar::getNameTagColor(bool is_friend)
else
{
color_name = "NameTagMismatch";
- }
+ }
}
else
{
@@ -3370,9 +3382,9 @@ bool LLVOAvatar::isVisuallyMuted()
static LLCachedControl<U32> max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit");
static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit");
- return LLMuteList::getInstance()->isMuted(getID()) ||
- (mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) ||
- (mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f);
+ return LLMuteList::getInstance()->isMuted(getID())
+ || (mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0)
+ || (mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f);
}
//------------------------------------------------------------------------
@@ -3413,8 +3425,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
}
}
- LLVector3d root_pos_global;
-
if (!mIsBuilt)
{
return FALSE;
@@ -3428,7 +3438,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
{
mTimeVisible.reset();
}
-
//--------------------------------------------------------------------
// the rest should only be done occasionally for far away avatars
@@ -3823,10 +3832,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
if ( playSound )
{
-// F32 gain = clamp_rescale( mSpeedAccum,
-// AUDIO_STEP_LO_SPEED, AUDIO_STEP_HI_SPEED,
-// AUDIO_STEP_LO_GAIN, AUDIO_STEP_HI_GAIN );
-
const F32 STEP_VOLUME = 0.1f;
const LLUUID& step_sound_id = getStepSound();
@@ -4043,13 +4048,6 @@ void LLVOAvatar::updateVisibility()
{
releaseMeshData();
}
- // this breaks off-screen chat bubbles
- //if (mNameText)
- //{
- // mNameText->markDead();
- // mNameText = NULL;
- // sNumVisibleChatBubbles--;
- //}
}
mVisible = visible;
@@ -4065,46 +4063,6 @@ bool LLVOAvatar::shouldAlphaMask()
}
-U32 LLVOAvatar::renderSkinnedAttachments()
-{
- /*U32 num_indices = 0;
-
- const U32 data_mask = LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_NORMAL |
- LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_COLOR |
- LLVertexBuffer::MAP_WEIGHT4;
-
- for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- const LLViewerObject* attached_object = (*attachment_iter);
- if (attached_object && !attached_object->isHUDAttachment())
- {
- const LLDrawable* drawable = attached_object->mDrawable;
- if (drawable)
- {
- for (S32 i = 0; i < drawable->getNumFaces(); ++i)
- {
- LLFace* face = drawable->getFace(i);
- if (face->isState(LLFace::RIGGED))
- {
-
- }
- }
- }
- }
-
- return num_indices;*/
- return 0;
-}
-
//-----------------------------------------------------------------------------
// renderSkinned()
//-----------------------------------------------------------------------------
@@ -4125,11 +4083,11 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
{ //LOD changed or new mesh created, allocate new vertex buffer if needed
if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4)
{
- updateMeshData();
+ updateMeshData();
mDirtyMesh = 0;
- mNeedsSkin = TRUE;
- mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
- }
+ mNeedsSkin = TRUE;
+ mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
+ }
}
if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0)
@@ -5790,36 +5748,34 @@ BOOL LLVOAvatar::updateJointLODs()
F32 avatar_num_factor = clamp_rescale((F32)sNumVisibleAvatars, 8, 25, 1.f, avatar_num_min_factor);
F32 area_scale = 0.16f;
+ if (isSelf())
{
- if (isSelf())
- {
- if(gAgentCamera.cameraCustomizeAvatar() || gAgentCamera.cameraMouselook())
- {
- mAdjustedPixelArea = MAX_PIXEL_AREA;
- }
- else
- {
- mAdjustedPixelArea = mPixelArea*area_scale;
- }
- }
- else if (mIsDummy)
+ if(gAgentCamera.cameraCustomizeAvatar() || gAgentCamera.cameraMouselook())
{
mAdjustedPixelArea = MAX_PIXEL_AREA;
}
else
{
- // reported avatar pixel area is dependent on avatar render load, based on number of visible avatars
- mAdjustedPixelArea = (F32)mPixelArea * area_scale * lod_factor * lod_factor * avatar_num_factor * avatar_num_factor;
+ mAdjustedPixelArea = mPixelArea*area_scale;
}
+ }
+ else if (mIsDummy)
+ {
+ mAdjustedPixelArea = MAX_PIXEL_AREA;
+ }
+ else
+ {
+ // reported avatar pixel area is dependent on avatar render load, based on number of visible avatars
+ mAdjustedPixelArea = (F32)mPixelArea * area_scale * lod_factor * lod_factor * avatar_num_factor * avatar_num_factor;
+ }
- // now select meshes to render based on adjusted pixel area
- BOOL res = mRoot.updateLOD(mAdjustedPixelArea, TRUE);
- if (res)
- {
- sNumLODChangesThisFrame++;
- dirtyMesh(2);
- return TRUE;
- }
+ // now select meshes to render based on adjusted pixel area
+ BOOL res = mRoot.updateLOD(mAdjustedPixelArea, TRUE);
+ if (res)
+ {
+ sNumLODChangesThisFrame++;
+ dirtyMesh(2);
+ return TRUE;
}
return FALSE;
@@ -6109,25 +6065,18 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
if ( pVObj )
{
const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID(), pVObj );
- if ( pSkinData )
- {
- const int jointCnt = pSkinData->mJointNames.size();
- bool fullRig = ( jointCnt>=20 ) ? true : false;
- if ( fullRig )
+ if (pSkinData
+ && pSkinData->mJointNames.size() > 20 // full rig
+ && pSkinData->mAlternateBindMatrix.size() > 0)
+ {
+ LLVOAvatar::resetJointPositionsToDefault();
+ //Need to handle the repositioning of the cam, updating rig data etc during outfit editing
+ //This handles the case where we detach a replacement rig.
+ if ( gAgentCamera.cameraCustomizeAvatar() )
{
- const int bindCnt = pSkinData->mAlternateBindMatrix.size();
- if ( bindCnt > 0 )
- {
- LLVOAvatar::resetJointPositionsToDefault();
- //Need to handle the repositioning of the cam, updating rig data etc during outfit editing
- //This handles the case where we detach a replacement rig.
- if ( gAgentCamera.cameraCustomizeAvatar() )
- {
- gAgent.unpauseAnimation();
- //Still want to refocus on head bone
- gAgentCamera.changeCameraToCustomizeAvatar();
- }
- }
+ gAgent.unpauseAnimation();
+ //Still want to refocus on head bone
+ gAgentCamera.changeCameraToCustomizeAvatar();
}
}
}
@@ -6281,11 +6230,7 @@ void LLVOAvatar::getOffObject()
at_axis.mV[VZ] = 0.f;
at_axis.normalize();
gAgent.resetAxes(at_axis);
-
- //reset orientation
-// mRoot.setRotation(avWorldRot);
gAgentCamera.setThirdPersonHeadOffset(LLVector3(0.f, 0.f, 1.f));
-
gAgentCamera.setSitCamera(LLUUID::null);
}
}
@@ -6335,7 +6280,6 @@ LLColor4 LLVOAvatar::getGlobalColor( const std::string& color_name ) const
}
else
{
-// return LLColor4( .5f, .5f, .5f, .5f );
return LLColor4( 0.f, 1.f, 1.f, 1.f ); // good debugging color
}
}
@@ -7067,10 +7011,6 @@ LLBBox LLVOAvatar::getHUDBBox() const
return bbox;
}
-void LLVOAvatar::rebuildHUD()
-{
-}
-
//-----------------------------------------------------------------------------
// onFirstTEMessageReceived()
//-----------------------------------------------------------------------------
@@ -7192,7 +7132,10 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
&& baked_index != BAKED_SKIRT)
{
setTEImage(mBakedTextureDatas[baked_index].mTextureIndex,
- LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureIndex, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+ LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureIndex,
+ TRUE,
+ LLViewerTexture::BOOST_NONE,
+ LLViewerTexture::LOD_TEXTURE));
}
}
@@ -7483,11 +7426,6 @@ void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_
// Called when baked texture is loaded and also when we start up with a baked texture
void LLVOAvatar::useBakedTexture( const LLUUID& id )
{
- /* if(id == head_baked->getID())
- mHeadBakedLoaded = TRUE;
- mLastHeadBakedID = id;
- mHeadMesh0.setTexture( head_baked );
- mHeadMesh1.setTexture( head_baked ); */
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
LLViewerTexture* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex, 0 );
@@ -7718,111 +7656,111 @@ LLVOAvatar::LLVOAvatarXmlInfo::~LLVOAvatarXmlInfo()
std::for_each(mMorphMaskInfoList.begin(), mMorphMaskInfoList.end(), DeletePointer());
}
-//-----------------------------------------------------------------------------
-// LLVOAvatarBoneInfo::parseXml()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatarBoneInfo::parseXml(LLXmlTreeNode* node)
-{
- if (node->hasName("bone"))
- {
- mIsJoint = TRUE;
- static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
- if (!node->getFastAttributeString(name_string, mName))
- {
- llwarns << "Bone without name" << llendl;
- return FALSE;
- }
- }
- else if (node->hasName("collision_volume"))
- {
- mIsJoint = FALSE;
- static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
- if (!node->getFastAttributeString(name_string, mName))
- {
- mName = "Collision Volume";
- }
- }
- else
- {
- llwarns << "Invalid node " << node->getName() << llendl;
- return FALSE;
- }
-
- static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos");
- if (!node->getFastAttributeVector3(pos_string, mPos))
- {
- llwarns << "Bone without position" << llendl;
- return FALSE;
- }
-
- static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot");
- if (!node->getFastAttributeVector3(rot_string, mRot))
- {
- llwarns << "Bone without rotation" << llendl;
- return FALSE;
- }
-
- static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
- if (!node->getFastAttributeVector3(scale_string, mScale))
- {
- llwarns << "Bone without scale" << llendl;
- return FALSE;
- }
-
- if (mIsJoint)
- {
- static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot");
- if (!node->getFastAttributeVector3(pivot_string, mPivot))
- {
- llwarns << "Bone without pivot" << llendl;
- return FALSE;
- }
- }
-
- // parse children
- LLXmlTreeNode* child;
- for( child = node->getFirstChild(); child; child = node->getNextChild() )
- {
- LLVOAvatarBoneInfo *child_info = new LLVOAvatarBoneInfo;
- if (!child_info->parseXml(child))
- {
- delete child_info;
- return FALSE;
- }
- mChildList.push_back(child_info);
- }
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// LLVOAvatarSkeletonInfo::parseXml()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node)
-{
- static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones");
- if (!node->getFastAttributeS32(num_bones_string, mNumBones))
- {
- llwarns << "Couldn't find number of bones." << llendl;
- return FALSE;
- }
-
- static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes");
- node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes);
-
- LLXmlTreeNode* child;
- for( child = node->getFirstChild(); child; child = node->getNextChild() )
- {
- LLVOAvatarBoneInfo *info = new LLVOAvatarBoneInfo;
- if (!info->parseXml(child))
- {
- delete info;
- llwarns << "Error parsing bone in skeleton file" << llendl;
- return FALSE;
- }
- mBoneInfoList.push_back(info);
- }
- return TRUE;
-}
+////-----------------------------------------------------------------------------
+//// LLVOAvatarBoneInfo::parseXml()
+////-----------------------------------------------------------------------------
+//BOOL LLVOAvatarBoneInfo::parseXml(LLXmlTreeNode* node)
+//{
+// if (node->hasName("bone"))
+// {
+// mIsJoint = TRUE;
+// static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+// if (!node->getFastAttributeString(name_string, mName))
+// {
+// llwarns << "Bone without name" << llendl;
+// return FALSE;
+// }
+// }
+// else if (node->hasName("collision_volume"))
+// {
+// mIsJoint = FALSE;
+// static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+// if (!node->getFastAttributeString(name_string, mName))
+// {
+// mName = "Collision Volume";
+// }
+// }
+// else
+// {
+// llwarns << "Invalid node " << node->getName() << llendl;
+// return FALSE;
+// }
+//
+// static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos");
+// if (!node->getFastAttributeVector3(pos_string, mPos))
+// {
+// llwarns << "Bone without position" << llendl;
+// return FALSE;
+// }
+//
+// static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot");
+// if (!node->getFastAttributeVector3(rot_string, mRot))
+// {
+// llwarns << "Bone without rotation" << llendl;
+// return FALSE;
+// }
+//
+// static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
+// if (!node->getFastAttributeVector3(scale_string, mScale))
+// {
+// llwarns << "Bone without scale" << llendl;
+// return FALSE;
+// }
+//
+// if (mIsJoint)
+// {
+// static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot");
+// if (!node->getFastAttributeVector3(pivot_string, mPivot))
+// {
+// llwarns << "Bone without pivot" << llendl;
+// return FALSE;
+// }
+// }
+//
+// // parse children
+// LLXmlTreeNode* child;
+// for( child = node->getFirstChild(); child; child = node->getNextChild() )
+// {
+// LLVOAvatarBoneInfo *child_info = new LLVOAvatarBoneInfo;
+// if (!child_info->parseXml(child))
+// {
+// delete child_info;
+// return FALSE;
+// }
+// mChildList.push_back(child_info);
+// }
+// return TRUE;
+//}
+//
+////-----------------------------------------------------------------------------
+//// LLVOAvatarSkeletonInfo::parseXml()
+////-----------------------------------------------------------------------------
+//BOOL LLVOAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node)
+//{
+// static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones");
+// if (!node->getFastAttributeS32(num_bones_string, mNumBones))
+// {
+// llwarns << "Couldn't find number of bones." << llendl;
+// return FALSE;
+// }
+//
+// static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes");
+// node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes);
+//
+// LLXmlTreeNode* child;
+// for( child = node->getFirstChild(); child; child = node->getNextChild() )
+// {
+// LLVOAvatarBoneInfo *info = new LLVOAvatarBoneInfo;
+// if (!info->parseXml(child))
+// {
+// delete info;
+// llwarns << "Error parsing bone in skeleton file" << llendl;
+// return FALSE;
+// }
+// mBoneInfoList.push_back(info);
+// }
+// return TRUE;
+//}
//-----------------------------------------------------------------------------
// parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index dd0317f555..e84acd51ff 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -66,8 +66,9 @@ class LLVoiceVisualizer;
class LLHUDNameTag;
class LLHUDEffectSpiral;
class LLTexGlobalColor;
-class LLVOAvatarBoneInfo;
-class LLVOAvatarSkeletonInfo;
+struct LLVOAvatarBoneInfo;
+struct LLVOAvatarChildJoint;
+struct LLVOAvatarSkeletonInfo;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// LLVOAvatar
@@ -232,7 +233,7 @@ public:
void idleUpdateWindEffect();
void idleUpdateNameTag(const LLVector3& root_pos_last);
void idleUpdateNameTagText(BOOL new_name);
- LLVector3 idleUpdateNameTagPosition(const LLVector3& root_pos_last);
+ void idleUpdateNameTagPosition(const LLVector3& root_pos_last);
void idleUpdateNameTagAlpha(BOOL new_name, F32 alpha);
LLColor4 getNameTagColor(bool is_friend);
void clearNameTag();
@@ -317,6 +318,8 @@ public:
F32 mLastPelvisToFoot;
F32 mPelvisFixup;
F32 mLastPelvisFixup;
+ LLVector3 mCurRootToHeadOffset;
+ LLVector3 mTargetRootToHeadOffset;
LLVector3 mHeadOffset; // current head position
LLViewerJoint mRoot;
@@ -325,7 +328,7 @@ protected:
void buildCharacter();
virtual BOOL loadAvatar();
- BOOL setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
+ BOOL setupBone(const LLVOAvatarChildJoint& info, LLViewerJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
BOOL buildSkeleton(const LLVOAvatarSkeletonInfo *info);
private:
BOOL mIsBuilt; // state of deferred character building
@@ -369,7 +372,7 @@ public:
//--------------------------------------------------------------------
private:
static LLXmlTree sXMLTree; // avatar config file
- static LLXmlTree sSkeletonXMLTree; // avatar skeleton file
+ static LLXMLNodePtr sSkeletonXMLTree; // avatar skeleton file
/** Skeleton
** **
@@ -387,7 +390,6 @@ public:
U32 renderRigid();
U32 renderSkinned(EAvatarRenderPass pass);
F32 getLastSkinTime() { return mLastSkinTime; }
- U32 renderSkinnedAttachments();
U32 renderTransparent(BOOL first_pass);
void renderCollisionVolumes();
static void deleteCachedImages(bool clearAll=true);
@@ -735,7 +737,6 @@ public:
public:
BOOL hasHUDAttachment() const;
LLBBox getHUDBBox() const;
- void rebuildHUD();
void resetHUDAttachments();
BOOL canAttachMoreObjects() const;
BOOL canAttachMoreObjects(U32 n) const;
diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp
index 47060720e7..dcf33bce10 100644
--- a/indra/newview/llvoicevisualizer.cpp
+++ b/indra/newview/llvoicevisualizer.cpp
@@ -1,625 +1,642 @@
-/**
- * @file llvoicevisualizer.cpp
- * @brief Draws in-world speaking indicators.
- *
- * $LicenseInfo:firstyear=2000&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-//----------------------------------------------------------------------
-// Voice Visualizer
-// author: JJ Ventrella
-// (information about this stuff can be found in "llvoicevisualizer.h")
-//----------------------------------------------------------------------
-#include "llviewerprecompiledheaders.h"
-#include "llviewercontrol.h"
-#include "llglheaders.h"
-#include "llsphere.h"
-#include "llvoicevisualizer.h"
-#include "llviewercamera.h"
-#include "llviewerobject.h"
-#include "llviewertexture.h"
-#include "llviewertexturelist.h"
-#include "llvoiceclient.h"
-#include "llrender.h"
-
-//brent's wave image
-//29de489d-0491-fb00-7dab-f9e686d31e83
-
-
-//--------------------------------------------------------------------------------------
-// sound symbol constants
-//--------------------------------------------------------------------------------------
-const F32 HEIGHT_ABOVE_HEAD = 0.3f; // how many meters vertically above the av's head the voice symbol will appear
-const F32 RED_THRESHOLD = LLVoiceClient::OVERDRIVEN_POWER_LEVEL; // value above which speaking amplitude causes the voice symbol to turn red
-const F32 GREEN_THRESHOLD = 0.2f; // value above which speaking amplitude causes the voice symbol to turn green
-const F32 FADE_OUT_DURATION = 0.4f; // how many seconds it takes for a pair of waves to fade away
-const F32 EXPANSION_RATE = 1.0f; // how many seconds it takes for the waves to expand to twice their original size
-const F32 EXPANSION_MAX = 1.5f; // maximum size scale to which the waves can expand before popping back to 1.0
-const F32 WAVE_WIDTH_SCALE = 0.03f; // base width of the waves
-const F32 WAVE_HEIGHT_SCALE = 0.02f; // base height of the waves
-const F32 BASE_BRIGHTNESS = 0.7f; // gray level of the voice indicator when quiet (below green threshold)
-const F32 DOT_SIZE = 0.05f; // size of the dot billboard texture
-const F32 DOT_OPACITY = 0.7f; // how opaque the dot is
-const F32 WAVE_MOTION_RATE = 1.5f; // scalar applied to consecutive waves as a function of speaking amplitude
-
-//--------------------------------------------------------------------------------------
-// gesticulation constants
-//--------------------------------------------------------------------------------------
-const F32 DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE = 0.2f;
-const F32 DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE = 1.0f;
-
-//--------------------------------------------------------------------------------------
-// other constants
-//--------------------------------------------------------------------------------------
-const F32 ONE_HALF = 1.0f; // to clarify intent and reduce magic numbers in the code.
-const LLVector3 WORLD_UPWARD_DIRECTION = LLVector3( 0.0f, 0.0f, 1.0f ); // Z is up in SL
-
-
-//------------------------------------------------------------------
-// handles parameter updates
-//------------------------------------------------------------------
-static bool handleVoiceVisualizerPrefsChanged(const LLSD& newvalue)
-{
- // Note: Ignore the specific event value, we look up the ones we want
- LLVoiceVisualizer::setPreferences();
- return true;
-}
-
-//------------------------------------------------------------------
-// Initialize the statics
-//------------------------------------------------------------------
-bool LLVoiceVisualizer::sPrefsInitialized = false;
-BOOL LLVoiceVisualizer::sLipSyncEnabled = FALSE;
-F32* LLVoiceVisualizer::sOoh = NULL;
-F32* LLVoiceVisualizer::sAah = NULL;
-U32 LLVoiceVisualizer::sOohs = 0;
-U32 LLVoiceVisualizer::sAahs = 0;
-F32 LLVoiceVisualizer::sOohAahRate = 0.0f;
-F32* LLVoiceVisualizer::sOohPowerTransfer = NULL;
-U32 LLVoiceVisualizer::sOohPowerTransfers = 0;
-F32 LLVoiceVisualizer::sOohPowerTransfersf = 0.0f;
-F32* LLVoiceVisualizer::sAahPowerTransfer = NULL;
-U32 LLVoiceVisualizer::sAahPowerTransfers = 0;
-F32 LLVoiceVisualizer::sAahPowerTransfersf = 0.0f;
-
-
-//-----------------------------------------------
-// constructor
-//-----------------------------------------------
-LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
-:LLHUDEffect( type )
-{
- mCurrentTime = mTimer.getTotalSeconds();
- mPreviousTime = mCurrentTime;
- mStartTime = mCurrentTime;
- mVoiceSourceWorldPosition = LLVector3( 0.0f, 0.0f, 0.0f );
- mSpeakingAmplitude = 0.0f;
- mCurrentlySpeaking = false;
- mVoiceEnabled = false;
- mMinGesticulationAmplitude = DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE;
- mMaxGesticulationAmplitude = DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE;
- mSoundSymbol.mActive = true;
- mSoundSymbol.mPosition = LLVector3( 0.0f, 0.0f, 0.0f );
-
- mTimer.reset();
-
- const char* sound_level_img[] =
- {
- "voice_meter_dot.j2c",
- "voice_meter_rings.j2c",
- "voice_meter_rings.j2c",
- "voice_meter_rings.j2c",
- "voice_meter_rings.j2c",
- "voice_meter_rings.j2c",
- "voice_meter_rings.j2c"
- };
-
- for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
- {
- mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime;
- mSoundSymbol.mTexture [i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FALSE, LLViewerTexture::BOOST_UI);
- mSoundSymbol.mWaveActive [i] = false;
- mSoundSymbol.mWaveOpacity [i] = 1.0f;
- mSoundSymbol.mWaveExpansion [i] = 1.0f;
- }
-
- mSoundSymbol.mTexture[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
-
- // The first instance loads the initial state from prefs.
- if (!sPrefsInitialized)
- {
- setPreferences();
-
- // Set up our listener to get updates on all prefs values we care about.
- gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
- gSavedSettings.getControl("LipSyncOohAahRate")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
- gSavedSettings.getControl("LipSyncOoh")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
- gSavedSettings.getControl("LipSyncAah")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
- gSavedSettings.getControl("LipSyncOohPowerTransfer")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
- gSavedSettings.getControl("LipSyncAahPowerTransfer")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
-
- sPrefsInitialized = true;
- }
-
-}//---------------------------------------------------
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setMinGesticulationAmplitude( F32 m )
-{
- mMinGesticulationAmplitude = m;
-
-}//---------------------------------------------------
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setMaxGesticulationAmplitude( F32 m )
-{
- mMaxGesticulationAmplitude = m;
-
-}//---------------------------------------------------
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setVoiceEnabled( bool v )
-{
- mVoiceEnabled = v;
-
-}//---------------------------------------------------
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setStartSpeaking()
-{
- mStartTime = mTimer.getTotalSeconds();
- mCurrentlySpeaking = true;
- mSoundSymbol.mActive = true;
-
-}//---------------------------------------------------
-
-
-//---------------------------------------------------
-bool LLVoiceVisualizer::getCurrentlySpeaking()
-{
- return mCurrentlySpeaking;
-
-}//---------------------------------------------------
-
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setStopSpeaking()
-{
- mCurrentlySpeaking = false;
- mSpeakingAmplitude = 0.0f;
-
-}//---------------------------------------------------
-
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setSpeakingAmplitude( F32 a )
-{
- mSpeakingAmplitude = a;
-
-}//---------------------------------------------------
-
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setPreferences( )
-{
- sLipSyncEnabled = gSavedSettings.getBOOL("LipSyncEnabled");
- sOohAahRate = gSavedSettings.getF32("LipSyncOohAahRate");
-
- std::string oohString = gSavedSettings.getString("LipSyncOoh");
- lipStringToF32s (oohString, sOoh, sOohs);
-
- std::string aahString = gSavedSettings.getString("LipSyncAah");
- lipStringToF32s (aahString, sAah, sAahs);
-
- std::string oohPowerString = gSavedSettings.getString("LipSyncOohPowerTransfer");
- lipStringToF32s (oohPowerString, sOohPowerTransfer, sOohPowerTransfers);
- sOohPowerTransfersf = (F32) sOohPowerTransfers;
-
- std::string aahPowerString = gSavedSettings.getString("LipSyncAahPowerTransfer");
- lipStringToF32s (aahPowerString, sAahPowerTransfer, sAahPowerTransfers);
- sAahPowerTransfersf = (F32) sAahPowerTransfers;
-
-}//---------------------------------------------------
-
-
-//---------------------------------------------------
-// convert a string of digits to an array of floats.
-// the result for each digit is the value of the
-// digit multiplied by 0.11
-//---------------------------------------------------
-void LLVoiceVisualizer::lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s )
-{
- delete[] out_F32s; // get rid of the current array
-
- count_F32s = in_string.length();
- if (count_F32s == 0)
- {
- // we don't like zero length arrays
-
- count_F32s = 1;
- out_F32s = new F32[1];
- out_F32s[0] = 0.0f;
- }
- else
- {
- out_F32s = new F32[count_F32s];
-
- for (U32 i=0; i<count_F32s; i++)
- {
- // we convert the characters 0 to 9 to their numeric value
- // anything else we take the low order four bits with a ceiling of 9
-
- U8 digit = in_string[i];
- U8 four_bits = digit % 16;
- if (four_bits > 9)
- {
- four_bits = 9;
- }
- out_F32s[i] = 0.11f * (F32) four_bits;
- }
- }
-
-}//---------------------------------------------------
-
-
-//--------------------------------------------------------------------------
-// find the amount to blend the ooh and aah mouth morphs
-//--------------------------------------------------------------------------
-void LLVoiceVisualizer::lipSyncOohAah( F32& ooh, F32& aah )
-{
- if( ( sLipSyncEnabled == TRUE ) && mCurrentlySpeaking )
- {
- U32 transfer_index = (U32) (sOohPowerTransfersf * mSpeakingAmplitude);
- if (transfer_index >= sOohPowerTransfers)
- {
- transfer_index = sOohPowerTransfers - 1;
- }
- F32 transfer_ooh = sOohPowerTransfer[transfer_index];
-
- transfer_index = (U32) (sAahPowerTransfersf * mSpeakingAmplitude);
- if (transfer_index >= sAahPowerTransfers)
- {
- transfer_index = sAahPowerTransfers - 1;
- }
- F32 transfer_aah = sAahPowerTransfer[transfer_index];
-
- F64 current_time = mTimer.getTotalSeconds();
- F64 elapsed_time = current_time - mStartTime;
- U32 elapsed_frames = (U32) (elapsed_time * sOohAahRate);
- U32 elapsed_oohs = elapsed_frames % sOohs;
- U32 elapsed_aahs = elapsed_frames % sAahs;
-
- ooh = transfer_ooh * sOoh[elapsed_oohs];
- aah = transfer_aah * sAah[elapsed_aahs];
-
- /*
- llinfos << " elapsed frames " << elapsed_frames
- << " ooh " << ooh
- << " aah " << aah
- << " transfer ooh" << transfer_ooh
- << " transfer aah" << transfer_aah
- << " start time " << mStartTime
- << " current time " << current_time
- << " elapsed time " << elapsed_time
- << " elapsed oohs " << elapsed_oohs
- << " elapsed aahs " << elapsed_aahs
- << llendl;
- */
- }
- else
- {
- ooh = 0.0f;
- aah = 0.0f;
- }
-
-}//---------------------------------------------------
-
-
-//---------------------------------------------------
-// this method is inherited from HUD Effect
-//---------------------------------------------------
-void LLVoiceVisualizer::render()
-{
- if ( ! mVoiceEnabled )
- {
- return;
- }
-
- if ( mSoundSymbol.mActive )
- {
- mPreviousTime = mCurrentTime;
- mCurrentTime = mTimer.getTotalSeconds();
-
- //---------------------------------------------------------------
- // set the sound symbol position over the source (avatar's head)
- //---------------------------------------------------------------
- mSoundSymbol.mPosition = mVoiceSourceWorldPosition + WORLD_UPWARD_DIRECTION * HEIGHT_ABOVE_HEAD;
-
- //---------------------------------------------------------------
- // some gl state
- //---------------------------------------------------------------
- LLGLSPipelineAlpha alpha_blend;
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
-
- //-------------------------------------------------------------
- // create coordinates of the geometry for the dot
- //-------------------------------------------------------------
- LLViewerCamera* camera = LLViewerCamera::getInstance();
- LLVector3 l = camera->getLeftAxis() * DOT_SIZE;
- LLVector3 u = camera->getUpAxis() * DOT_SIZE;
-
- LLVector3 bottomLeft = mSoundSymbol.mPosition + l - u;
- LLVector3 bottomRight = mSoundSymbol.mPosition - l - u;
- LLVector3 topLeft = mSoundSymbol.mPosition + l + u;
- LLVector3 topRight = mSoundSymbol.mPosition - l + u;
-
- //-----------------------------
- // bind texture 0 (the dot)
- //-----------------------------
- gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[0]);
-
- //-------------------------------------------------------------
- // now render the dot
- //-------------------------------------------------------------
- gGL.color4fv( LLColor4( 1.0f, 1.0f, 1.0f, DOT_OPACITY ).mV );
-
- gGL.begin( LLRender::TRIANGLE_STRIP );
- gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV );
- gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
- gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
- gGL.end();
-
- gGL.begin( LLRender::TRIANGLE_STRIP );
- gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
- gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV );
- gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
- gGL.end();
-
-
-
- //--------------------------------------------------------------------------------------
- // if currently speaking, trigger waves (1 through 6) based on speaking amplitude
- //--------------------------------------------------------------------------------------
- if ( mCurrentlySpeaking )
- {
- F32 min = 0.2f;
- F32 max = 0.7f;
- F32 fraction = ( mSpeakingAmplitude - min ) / ( max - min );
-
- // in case mSpeakingAmplitude > max....
- if ( fraction > 1.0f )
- {
- fraction = 1.0f;
- }
-
- S32 level = 1 + (int)( fraction * ( NUM_VOICE_SYMBOL_WAVES - 2 ) );
-
- for (int i=0; i<level+1; i++)
- {
- mSoundSymbol.mWaveActive [i] = true;
- mSoundSymbol.mWaveOpacity [i] = 1.0f;
- mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime;
- }
-
- } // if currently speaking
-
- //---------------------------------------------------
- // determine color
- //---------------------------------------------------
- F32 red = 0.0f;
- F32 green = 0.0f;
- F32 blue = 0.0f;
- if ( mSpeakingAmplitude < RED_THRESHOLD )
- {
- if ( mSpeakingAmplitude < GREEN_THRESHOLD )
- {
- red = BASE_BRIGHTNESS;
- green = BASE_BRIGHTNESS;
- blue = BASE_BRIGHTNESS;
- }
- else
- {
- //---------------------------------------------------
- // fade from gray to bright green
- //---------------------------------------------------
- F32 fraction = ( mSpeakingAmplitude - GREEN_THRESHOLD ) / ( 1.0f - GREEN_THRESHOLD );
- red = BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS );
- green = BASE_BRIGHTNESS + fraction * ( 1.0f - BASE_BRIGHTNESS );
- blue = BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS );
- }
- }
- else
- {
- //---------------------------------------------------
- // redish
- //---------------------------------------------------
- red = 1.0f;
- green = 0.2f;
- blue = 0.2f;
- }
-
- for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
- {
- if ( mSoundSymbol.mWaveActive[i] )
- {
- F32 fadeOutFraction = (F32)( mCurrentTime - mSoundSymbol.mWaveFadeOutStartTime[i] ) / FADE_OUT_DURATION;
-
- mSoundSymbol.mWaveOpacity[i] = 1.0f - fadeOutFraction;
-
- if ( mSoundSymbol.mWaveOpacity[i] < 0.0f )
- {
- mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime;
- mSoundSymbol.mWaveOpacity [i] = 0.0f;
- mSoundSymbol.mWaveActive [i] = false;
- }
-
- //----------------------------------------------------------------------------------
- // This is where we calculate the expansion of the waves - that is, the
- // rate at which they are scaled greater than 1.0 so that they grow over time.
- //----------------------------------------------------------------------------------
- F32 timeSlice = (F32)( mCurrentTime - mPreviousTime );
- F32 waveSpeed = mSpeakingAmplitude * WAVE_MOTION_RATE;
- mSoundSymbol.mWaveExpansion[i] *= ( 1.0f + EXPANSION_RATE * timeSlice * waveSpeed );
-
- if ( mSoundSymbol.mWaveExpansion[i] > EXPANSION_MAX )
- {
- mSoundSymbol.mWaveExpansion[i] = 1.0f;
- }
-
- //----------------------------------------------------------------------------------
- // create geometry for the wave billboard textures
- //----------------------------------------------------------------------------------
- F32 width = i * WAVE_WIDTH_SCALE * mSoundSymbol.mWaveExpansion[i];
- F32 height = i * WAVE_HEIGHT_SCALE * mSoundSymbol.mWaveExpansion[i];
-
- LLVector3 l = camera->getLeftAxis() * width;
- LLVector3 u = camera->getUpAxis() * height;
-
- LLVector3 bottomLeft = mSoundSymbol.mPosition + l - u;
- LLVector3 bottomRight = mSoundSymbol.mPosition - l - u;
- LLVector3 topLeft = mSoundSymbol.mPosition + l + u;
- LLVector3 topRight = mSoundSymbol.mPosition - l + u;
-
- gGL.color4fv( LLColor4( red, green, blue, mSoundSymbol.mWaveOpacity[i] ).mV );
- gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[i]);
-
-
- //---------------------------------------------------
- // now, render the mofo
- //---------------------------------------------------
- gGL.begin( LLRender::TRIANGLE_STRIP );
- gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV );
- gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
- gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
- gGL.end();
-
- gGL.begin( LLRender::TRIANGLE_STRIP );
- gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
- gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV );
- gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
- gGL.end();
-
- } //if ( mSoundSymbol.mWaveActive[i] )
-
- }// for loop
-
- }//if ( mSoundSymbol.mActive )
-
-}//---------------------------------------------------
-
-
-
-
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setVoiceSourceWorldPosition( const LLVector3 &p )
-{
- mVoiceSourceWorldPosition = p;
-
-}//---------------------------------------------------
-
-//---------------------------------------------------
-VoiceGesticulationLevel LLVoiceVisualizer::getCurrentGesticulationLevel()
-{
- VoiceGesticulationLevel gesticulationLevel = VOICE_GESTICULATION_LEVEL_OFF; //default
-
- //-----------------------------------------------------------------------------------------
- // Within the range of gesticulation amplitudes, the sound signal is split into
- // three equal amplitude regimes, each specifying one of three gesticulation levels.
- //-----------------------------------------------------------------------------------------
- F32 range = mMaxGesticulationAmplitude - mMinGesticulationAmplitude;
-
- if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.5f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_HIGH; }
- else if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.25f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_MEDIUM; }
- else if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.00000f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_LOW; }
-
- return gesticulationLevel;
-
-}//---------------------------------------------------
-
-
-
-//------------------------------------
-// Destructor
-//------------------------------------
-LLVoiceVisualizer::~LLVoiceVisualizer()
-{
-}//----------------------------------------------
-
-
-//---------------------------------------------------
-// "packData" is inherited from HUDEffect
-//---------------------------------------------------
-void LLVoiceVisualizer::packData(LLMessageSystem *mesgsys)
-{
- // Pack the default data
- LLHUDEffect::packData(mesgsys);
-
- // TODO -- pack the relevant data for voice effects
- // we'll come up with some cool configurations....TBD
- //U8 packed_data[41];
- //mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, 41);
- U8 packed_data = 0;
- mesgsys->addBinaryDataFast(_PREHASH_TypeData, &packed_data, 1);
-}
-
-
-//---------------------------------------------------
-// "unpackData" is inherited from HUDEffect
-//---------------------------------------------------
-void LLVoiceVisualizer::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
-{
- // TODO -- find the speaker, unpack binary data, set the properties of this effect
- /*
- LLHUDEffect::unpackData(mesgsys, blocknum);
- LLUUID source_id;
- LLUUID target_id;
- S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData);
- if (size != 1)
- {
- llwarns << "Voice effect with bad size " << size << llendl;
- return;
- }
- mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, 1, blocknum);
- */
-}
-
-
-//------------------------------------------------------------------
-// this method is inherited from HUD Effect
-//------------------------------------------------------------------
-void LLVoiceVisualizer::markDead()
-{
- mCurrentlySpeaking = false;
- mVoiceEnabled = false;
- mSoundSymbol.mActive = false;
-
- LLHUDEffect::markDead();
-}//------------------------------------------------------------------
-
-
-
-
-
-
-
-
+/**
+ * @file llvoicevisualizer.cpp
+ * @brief Draws in-world speaking indicators.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+//----------------------------------------------------------------------
+// Voice Visualizer
+// author: JJ Ventrella
+// (information about this stuff can be found in "llvoicevisualizer.h")
+//----------------------------------------------------------------------
+#include "llviewerprecompiledheaders.h"
+#include "llviewercontrol.h"
+#include "llglheaders.h"
+#include "llsphere.h"
+#include "llvoicevisualizer.h"
+#include "llviewercamera.h"
+#include "llviewerobject.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
+#include "llvoiceclient.h"
+#include "llrender.h"
+
+//brent's wave image
+//29de489d-0491-fb00-7dab-f9e686d31e83
+
+
+#ifdef XXX_STINSON_CHUI_REWORK
+//--------------------------------------------------------------------------------------
+// sound symbol constants
+//--------------------------------------------------------------------------------------
+const F32 HEIGHT_ABOVE_HEAD = 0.3f; // how many meters vertically above the av's head the voice symbol will appear
+const F32 RED_THRESHOLD = LLVoiceClient::OVERDRIVEN_POWER_LEVEL; // value above which speaking amplitude causes the voice symbol to turn red
+const F32 GREEN_THRESHOLD = 0.2f; // value above which speaking amplitude causes the voice symbol to turn green
+const F32 FADE_OUT_DURATION = 0.4f; // how many seconds it takes for a pair of waves to fade away
+const F32 EXPANSION_RATE = 1.0f; // how many seconds it takes for the waves to expand to twice their original size
+const F32 EXPANSION_MAX = 1.5f; // maximum size scale to which the waves can expand before popping back to 1.0
+const F32 WAVE_WIDTH_SCALE = 0.03f; // base width of the waves
+const F32 WAVE_HEIGHT_SCALE = 0.02f; // base height of the waves
+const F32 BASE_BRIGHTNESS = 0.7f; // gray level of the voice indicator when quiet (below green threshold)
+const F32 DOT_SIZE = 0.05f; // size of the dot billboard texture
+const F32 DOT_OPACITY = 0.7f; // how opaque the dot is
+const F32 WAVE_MOTION_RATE = 1.5f; // scalar applied to consecutive waves as a function of speaking amplitude
+#endif // XXX_STINSON_CHUI_REWORK
+
+//--------------------------------------------------------------------------------------
+// gesticulation constants
+//--------------------------------------------------------------------------------------
+const F32 DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE = 0.2f;
+const F32 DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE = 1.0f;
+
+#ifdef XXX_STINSON_CHUI_REWORK
+//--------------------------------------------------------------------------------------
+// other constants
+//--------------------------------------------------------------------------------------
+const F32 ONE_HALF = 1.0f; // to clarify intent and reduce magic numbers in the code.
+const LLVector3 WORLD_UPWARD_DIRECTION = LLVector3( 0.0f, 0.0f, 1.0f ); // Z is up in SL
+#endif // XXX_STINSON_CHUI_REWORK
+
+//------------------------------------------------------------------
+// Initialize the statics
+//------------------------------------------------------------------
+bool LLVoiceVisualizer::sPrefsInitialized = false;
+BOOL LLVoiceVisualizer::sLipSyncEnabled = FALSE;
+F32* LLVoiceVisualizer::sOoh = NULL;
+F32* LLVoiceVisualizer::sAah = NULL;
+U32 LLVoiceVisualizer::sOohs = 0;
+U32 LLVoiceVisualizer::sAahs = 0;
+F32 LLVoiceVisualizer::sOohAahRate = 0.0f;
+F32* LLVoiceVisualizer::sOohPowerTransfer = NULL;
+U32 LLVoiceVisualizer::sOohPowerTransfers = 0;
+F32 LLVoiceVisualizer::sOohPowerTransfersf = 0.0f;
+F32* LLVoiceVisualizer::sAahPowerTransfer = NULL;
+U32 LLVoiceVisualizer::sAahPowerTransfers = 0;
+F32 LLVoiceVisualizer::sAahPowerTransfersf = 0.0f;
+
+
+//-----------------------------------------------
+// constructor
+//-----------------------------------------------
+#ifdef XXX_STINSON_CHUI_REWORK
+LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
+#else // XXX_STINSON_CHUI_REWORK
+LLVoiceVisualizer::LLVoiceVisualizer()
+ : LLRefCount(),
+ mTimer(),
+ mStartTime(0.0),
+ mCurrentlySpeaking(false),
+ mSpeakingAmplitude(0.0f),
+ mMaxGesticulationAmplitude(DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE),
+ mMinGesticulationAmplitude(DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE)
+#endif // XXX_STINSON_CHUI_REWORK
+{
+#ifdef XXX_STINSON_CHUI_REWORK
+ mCurrentTime = mTimer.getTotalSeconds();
+ mPreviousTime = mCurrentTime;
+ mStartTime = mCurrentTime;
+#else // XXX_STINSON_CHUI_REWORK
+ mStartTime = mTimer.getTotalSeconds();
+#endif // XXX_STINSON_CHUI_REWORK
+#ifdef XXX_STINSON_CHUI_REWORK
+ mVoiceSourceWorldPosition = LLVector3( 0.0f, 0.0f, 0.0f );
+ mSpeakingAmplitude = 0.0f;
+ mCurrentlySpeaking = false;
+ mVoiceEnabled = false;
+ mMinGesticulationAmplitude = DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE;
+ mMaxGesticulationAmplitude = DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE;
+ mSoundSymbol.mActive = true;
+ mSoundSymbol.mPosition = LLVector3( 0.0f, 0.0f, 0.0f );
+#endif // XXX_STINSON_CHUI_REWORK
+
+ mTimer.reset();
+
+#ifdef XXX_STINSON_CHUI_REWORK
+ const char* sound_level_img[] =
+ {
+ "voice_meter_dot.j2c",
+ "voice_meter_rings.j2c",
+ "voice_meter_rings.j2c",
+ "voice_meter_rings.j2c",
+ "voice_meter_rings.j2c",
+ "voice_meter_rings.j2c",
+ "voice_meter_rings.j2c"
+ };
+
+ for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
+ {
+ mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime;
+ mSoundSymbol.mTexture [i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FALSE, LLViewerTexture::BOOST_UI);
+ mSoundSymbol.mWaveActive [i] = false;
+ mSoundSymbol.mWaveOpacity [i] = 1.0f;
+ mSoundSymbol.mWaveExpansion [i] = 1.0f;
+ }
+
+ mSoundSymbol.mTexture[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+#endif // XXX_STINSON_CHUI_REWORK
+
+ // The first instance loads the initial state from prefs.
+ if (!sPrefsInitialized)
+ {
+ setPreferences();
+
+ // Set up our listener to get updates on all prefs values we care about.
+ gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+ gSavedSettings.getControl("LipSyncOohAahRate")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+ gSavedSettings.getControl("LipSyncOoh")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+ gSavedSettings.getControl("LipSyncAah")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+ gSavedSettings.getControl("LipSyncOohPowerTransfer")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+ gSavedSettings.getControl("LipSyncAahPowerTransfer")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+
+ sPrefsInitialized = true;
+ }
+
+}//---------------------------------------------------
+
+#ifdef XXX_STINSON_CHUI_REWORK
+//---------------------------------------------------
+void LLVoiceVisualizer::setMinGesticulationAmplitude( F32 m )
+{
+ mMinGesticulationAmplitude = m;
+
+}//---------------------------------------------------
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setMaxGesticulationAmplitude( F32 m )
+{
+ mMaxGesticulationAmplitude = m;
+
+}//---------------------------------------------------
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setVoiceEnabled( bool v )
+{
+ mVoiceEnabled = v;
+
+}//---------------------------------------------------
+#endif // XXX_STINSON_CHUI_REWORK
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setStartSpeaking()
+{
+ mStartTime = mTimer.getTotalSeconds();
+ mCurrentlySpeaking = true;
+#ifdef XXX_STINSON_CHUI_REWORK
+ mSoundSymbol.mActive = true;
+#endif // XXX_STINSON_CHUI_REWORK
+
+}//---------------------------------------------------
+
+
+//---------------------------------------------------
+bool LLVoiceVisualizer::getCurrentlySpeaking()
+{
+ return mCurrentlySpeaking;
+
+}//---------------------------------------------------
+
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setStopSpeaking()
+{
+ mCurrentlySpeaking = false;
+ mSpeakingAmplitude = 0.0f;
+
+}//---------------------------------------------------
+
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setSpeakingAmplitude( F32 a )
+{
+ mSpeakingAmplitude = a;
+
+}//---------------------------------------------------
+
+//------------------------------------------------------------------
+// handles parameter updates
+//------------------------------------------------------------------
+bool LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged(const LLSD& newvalue)
+{
+ // Note: Ignore the specific event value, we look up the ones we want
+ LLVoiceVisualizer::setPreferences();
+ return true;
+}
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setPreferences( )
+{
+ sLipSyncEnabled = gSavedSettings.getBOOL("LipSyncEnabled");
+ sOohAahRate = gSavedSettings.getF32("LipSyncOohAahRate");
+
+ std::string oohString = gSavedSettings.getString("LipSyncOoh");
+ lipStringToF32s (oohString, sOoh, sOohs);
+
+ std::string aahString = gSavedSettings.getString("LipSyncAah");
+ lipStringToF32s (aahString, sAah, sAahs);
+
+ std::string oohPowerString = gSavedSettings.getString("LipSyncOohPowerTransfer");
+ lipStringToF32s (oohPowerString, sOohPowerTransfer, sOohPowerTransfers);
+ sOohPowerTransfersf = (F32) sOohPowerTransfers;
+
+ std::string aahPowerString = gSavedSettings.getString("LipSyncAahPowerTransfer");
+ lipStringToF32s (aahPowerString, sAahPowerTransfer, sAahPowerTransfers);
+ sAahPowerTransfersf = (F32) sAahPowerTransfers;
+
+}//---------------------------------------------------
+
+
+//---------------------------------------------------
+// convert a string of digits to an array of floats.
+// the result for each digit is the value of the
+// digit multiplied by 0.11
+//---------------------------------------------------
+void LLVoiceVisualizer::lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s )
+{
+ delete[] out_F32s; // get rid of the current array
+
+ count_F32s = in_string.length();
+ if (count_F32s == 0)
+ {
+ // we don't like zero length arrays
+
+ count_F32s = 1;
+ out_F32s = new F32[1];
+ out_F32s[0] = 0.0f;
+ }
+ else
+ {
+ out_F32s = new F32[count_F32s];
+
+ for (U32 i=0; i<count_F32s; i++)
+ {
+ // we convert the characters 0 to 9 to their numeric value
+ // anything else we take the low order four bits with a ceiling of 9
+
+ U8 digit = in_string[i];
+ U8 four_bits = digit % 16;
+ if (four_bits > 9)
+ {
+ four_bits = 9;
+ }
+ out_F32s[i] = 0.11f * (F32) four_bits;
+ }
+ }
+
+}//---------------------------------------------------
+
+
+//--------------------------------------------------------------------------
+// find the amount to blend the ooh and aah mouth morphs
+//--------------------------------------------------------------------------
+void LLVoiceVisualizer::lipSyncOohAah( F32& ooh, F32& aah )
+{
+ if( ( sLipSyncEnabled == TRUE ) && mCurrentlySpeaking )
+ {
+ U32 transfer_index = (U32) (sOohPowerTransfersf * mSpeakingAmplitude);
+ if (transfer_index >= sOohPowerTransfers)
+ {
+ transfer_index = sOohPowerTransfers - 1;
+ }
+ F32 transfer_ooh = sOohPowerTransfer[transfer_index];
+
+ transfer_index = (U32) (sAahPowerTransfersf * mSpeakingAmplitude);
+ if (transfer_index >= sAahPowerTransfers)
+ {
+ transfer_index = sAahPowerTransfers - 1;
+ }
+ F32 transfer_aah = sAahPowerTransfer[transfer_index];
+
+ F64 current_time = mTimer.getTotalSeconds();
+ F64 elapsed_time = current_time - mStartTime;
+ U32 elapsed_frames = (U32) (elapsed_time * sOohAahRate);
+ U32 elapsed_oohs = elapsed_frames % sOohs;
+ U32 elapsed_aahs = elapsed_frames % sAahs;
+
+ ooh = transfer_ooh * sOoh[elapsed_oohs];
+ aah = transfer_aah * sAah[elapsed_aahs];
+
+ /*
+ llinfos << " elapsed frames " << elapsed_frames
+ << " ooh " << ooh
+ << " aah " << aah
+ << " transfer ooh" << transfer_ooh
+ << " transfer aah" << transfer_aah
+ << " start time " << mStartTime
+ << " current time " << current_time
+ << " elapsed time " << elapsed_time
+ << " elapsed oohs " << elapsed_oohs
+ << " elapsed aahs " << elapsed_aahs
+ << llendl;
+ */
+ }
+ else
+ {
+ ooh = 0.0f;
+ aah = 0.0f;
+ }
+
+}//---------------------------------------------------
+
+
+#ifdef XXX_STINSON_CHUI_REWORK
+//---------------------------------------------------
+// this method is inherited from HUD Effect
+//---------------------------------------------------
+void LLVoiceVisualizer::render()
+{
+ if ( ! mVoiceEnabled )
+ {
+ return;
+ }
+
+ if ( mSoundSymbol.mActive )
+ {
+ mPreviousTime = mCurrentTime;
+ mCurrentTime = mTimer.getTotalSeconds();
+
+ //---------------------------------------------------------------
+ // set the sound symbol position over the source (avatar's head)
+ //---------------------------------------------------------------
+ mSoundSymbol.mPosition = mVoiceSourceWorldPosition + WORLD_UPWARD_DIRECTION * HEIGHT_ABOVE_HEAD;
+
+ //---------------------------------------------------------------
+ // some gl state
+ //---------------------------------------------------------------
+ LLGLSPipelineAlpha alpha_blend;
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+
+ //-------------------------------------------------------------
+ // create coordinates of the geometry for the dot
+ //-------------------------------------------------------------
+ LLViewerCamera* camera = LLViewerCamera::getInstance();
+ LLVector3 l = camera->getLeftAxis() * DOT_SIZE;
+ LLVector3 u = camera->getUpAxis() * DOT_SIZE;
+
+ LLVector3 bottomLeft = mSoundSymbol.mPosition + l - u;
+ LLVector3 bottomRight = mSoundSymbol.mPosition - l - u;
+ LLVector3 topLeft = mSoundSymbol.mPosition + l + u;
+ LLVector3 topRight = mSoundSymbol.mPosition - l + u;
+
+ //-----------------------------
+ // bind texture 0 (the dot)
+ //-----------------------------
+ gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[0]);
+
+ //-------------------------------------------------------------
+ // now render the dot
+ //-------------------------------------------------------------
+ gGL.color4fv( LLColor4( 1.0f, 1.0f, 1.0f, DOT_OPACITY ).mV );
+
+ gGL.begin( LLRender::TRIANGLE_STRIP );
+ gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV );
+ gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
+ gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
+ gGL.end();
+
+ gGL.begin( LLRender::TRIANGLE_STRIP );
+ gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
+ gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV );
+ gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
+ gGL.end();
+
+
+
+ //--------------------------------------------------------------------------------------
+ // if currently speaking, trigger waves (1 through 6) based on speaking amplitude
+ //--------------------------------------------------------------------------------------
+ if ( mCurrentlySpeaking )
+ {
+ F32 min = 0.2f;
+ F32 max = 0.7f;
+ F32 fraction = ( mSpeakingAmplitude - min ) / ( max - min );
+
+ // in case mSpeakingAmplitude > max....
+ if ( fraction > 1.0f )
+ {
+ fraction = 1.0f;
+ }
+
+ S32 level = 1 + (int)( fraction * ( NUM_VOICE_SYMBOL_WAVES - 2 ) );
+
+ for (int i=0; i<level+1; i++)
+ {
+ mSoundSymbol.mWaveActive [i] = true;
+ mSoundSymbol.mWaveOpacity [i] = 1.0f;
+ mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime;
+ }
+
+ } // if currently speaking
+
+ //---------------------------------------------------
+ // determine color
+ //---------------------------------------------------
+ F32 red = 0.0f;
+ F32 green = 0.0f;
+ F32 blue = 0.0f;
+ if ( mSpeakingAmplitude < RED_THRESHOLD )
+ {
+ if ( mSpeakingAmplitude < GREEN_THRESHOLD )
+ {
+ red = BASE_BRIGHTNESS;
+ green = BASE_BRIGHTNESS;
+ blue = BASE_BRIGHTNESS;
+ }
+ else
+ {
+ //---------------------------------------------------
+ // fade from gray to bright green
+ //---------------------------------------------------
+ F32 fraction = ( mSpeakingAmplitude - GREEN_THRESHOLD ) / ( 1.0f - GREEN_THRESHOLD );
+ red = BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS );
+ green = BASE_BRIGHTNESS + fraction * ( 1.0f - BASE_BRIGHTNESS );
+ blue = BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS );
+ }
+ }
+ else
+ {
+ //---------------------------------------------------
+ // redish
+ //---------------------------------------------------
+ red = 1.0f;
+ green = 0.2f;
+ blue = 0.2f;
+ }
+
+ for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
+ {
+ if ( mSoundSymbol.mWaveActive[i] )
+ {
+ F32 fadeOutFraction = (F32)( mCurrentTime - mSoundSymbol.mWaveFadeOutStartTime[i] ) / FADE_OUT_DURATION;
+
+ mSoundSymbol.mWaveOpacity[i] = 1.0f - fadeOutFraction;
+
+ if ( mSoundSymbol.mWaveOpacity[i] < 0.0f )
+ {
+ mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime;
+ mSoundSymbol.mWaveOpacity [i] = 0.0f;
+ mSoundSymbol.mWaveActive [i] = false;
+ }
+
+ //----------------------------------------------------------------------------------
+ // This is where we calculate the expansion of the waves - that is, the
+ // rate at which they are scaled greater than 1.0 so that they grow over time.
+ //----------------------------------------------------------------------------------
+ F32 timeSlice = (F32)( mCurrentTime - mPreviousTime );
+ F32 waveSpeed = mSpeakingAmplitude * WAVE_MOTION_RATE;
+ mSoundSymbol.mWaveExpansion[i] *= ( 1.0f + EXPANSION_RATE * timeSlice * waveSpeed );
+
+ if ( mSoundSymbol.mWaveExpansion[i] > EXPANSION_MAX )
+ {
+ mSoundSymbol.mWaveExpansion[i] = 1.0f;
+ }
+
+ //----------------------------------------------------------------------------------
+ // create geometry for the wave billboard textures
+ //----------------------------------------------------------------------------------
+ F32 width = i * WAVE_WIDTH_SCALE * mSoundSymbol.mWaveExpansion[i];
+ F32 height = i * WAVE_HEIGHT_SCALE * mSoundSymbol.mWaveExpansion[i];
+
+ LLVector3 l = camera->getLeftAxis() * width;
+ LLVector3 u = camera->getUpAxis() * height;
+
+ LLVector3 bottomLeft = mSoundSymbol.mPosition + l - u;
+ LLVector3 bottomRight = mSoundSymbol.mPosition - l - u;
+ LLVector3 topLeft = mSoundSymbol.mPosition + l + u;
+ LLVector3 topRight = mSoundSymbol.mPosition - l + u;
+
+ gGL.color4fv( LLColor4( red, green, blue, mSoundSymbol.mWaveOpacity[i] ).mV );
+ gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[i]);
+
+
+ //---------------------------------------------------
+ // now, render the mofo
+ //---------------------------------------------------
+ gGL.begin( LLRender::TRIANGLE_STRIP );
+ gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV );
+ gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
+ gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
+ gGL.end();
+
+ gGL.begin( LLRender::TRIANGLE_STRIP );
+ gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
+ gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV );
+ gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
+ gGL.end();
+
+ } //if ( mSoundSymbol.mWaveActive[i] )
+
+ }// for loop
+
+ }//if ( mSoundSymbol.mActive )
+
+}//---------------------------------------------------
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setVoiceSourceWorldPosition( const LLVector3 &p )
+{
+ mVoiceSourceWorldPosition = p;
+
+}//---------------------------------------------------
+#endif // XXX_STINSON_CHUI_REWORK
+
+//---------------------------------------------------
+VoiceGesticulationLevel LLVoiceVisualizer::getCurrentGesticulationLevel()
+{
+ VoiceGesticulationLevel gesticulationLevel = VOICE_GESTICULATION_LEVEL_OFF; //default
+
+ //-----------------------------------------------------------------------------------------
+ // Within the range of gesticulation amplitudes, the sound signal is split into
+ // three equal amplitude regimes, each specifying one of three gesticulation levels.
+ //-----------------------------------------------------------------------------------------
+ F32 range = mMaxGesticulationAmplitude - mMinGesticulationAmplitude;
+
+ if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.5f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_HIGH; }
+ else if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.25f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_MEDIUM; }
+ else if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.00000f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_LOW; }
+
+ return gesticulationLevel;
+
+}//---------------------------------------------------
+
+
+
+//------------------------------------
+// Destructor
+//------------------------------------
+LLVoiceVisualizer::~LLVoiceVisualizer()
+{
+}//----------------------------------------------
+
+
+#ifdef XXX_STINSON_CHUI_REWORK
+//---------------------------------------------------
+// "packData" is inherited from HUDEffect
+//---------------------------------------------------
+void LLVoiceVisualizer::packData(LLMessageSystem *mesgsys)
+{
+ // Pack the default data
+ LLHUDEffect::packData(mesgsys);
+
+ // TODO -- pack the relevant data for voice effects
+ // we'll come up with some cool configurations....TBD
+ //U8 packed_data[41];
+ //mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, 41);
+ U8 packed_data = 0;
+ mesgsys->addBinaryDataFast(_PREHASH_TypeData, &packed_data, 1);
+}
+
+
+//---------------------------------------------------
+// "unpackData" is inherited from HUDEffect
+//---------------------------------------------------
+void LLVoiceVisualizer::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
+{
+ // TODO -- find the speaker, unpack binary data, set the properties of this effect
+ /*
+ LLHUDEffect::unpackData(mesgsys, blocknum);
+ LLUUID source_id;
+ LLUUID target_id;
+ S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData);
+ if (size != 1)
+ {
+ llwarns << "Voice effect with bad size " << size << llendl;
+ return;
+ }
+ mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, 1, blocknum);
+ */
+}
+
+
+//------------------------------------------------------------------
+// this method is inherited from HUD Effect
+//------------------------------------------------------------------
+void LLVoiceVisualizer::markDead()
+{
+ mCurrentlySpeaking = false;
+ mVoiceEnabled = false;
+ mSoundSymbol.mActive = false;
+
+ LLHUDEffect::markDead();
+}//------------------------------------------------------------------
+
+#endif // XXX_STINSON_CHUI_REWORK
diff --git a/indra/newview/llvoicevisualizer.h b/indra/newview/llvoicevisualizer.h
index e434c7f3f1..6258de163d 100644
--- a/indra/newview/llvoicevisualizer.h
+++ b/indra/newview/llvoicevisualizer.h
@@ -42,7 +42,11 @@
#ifndef LL_VOICE_VISUALIZER_H
#define LL_VOICE_VISUALIZER_H
+#ifdef XXX_STINSON_CHUI_REWORK
#include "llhudeffect.h"
+#else // XXX_STINSON_CHUI_REWORK
+#include "llpointer.h"
+#endif // XXX_STINSON_CHUI_REWORK
//-----------------------------------------------------------------------------------------------
// The values of voice gesticulation represent energy levels for avatar animation, based on
@@ -60,34 +64,45 @@ enum VoiceGesticulationLevel
NUM_VOICE_GESTICULATION_LEVELS
};
+#ifdef XXX_STINSON_CHUI_REWORK
const static int NUM_VOICE_SYMBOL_WAVES = 7;
+#endif // XXX_STINSON_CHUI_REWORK
//----------------------------------------------------
// LLVoiceVisualizer class
//----------------------------------------------------
+#ifdef XXX_STINSON_CHUI_REWORK
class LLVoiceVisualizer : public LLHUDEffect
+#else // XXX_STINSON_CHUI_REWORK
+class LLVoiceVisualizer : public LLRefCount
+#endif // XXX_STINSON_CHUI_REWORK
{
//---------------------------------------------------
// public methods
//---------------------------------------------------
public:
- LLVoiceVisualizer ( const U8 type ); //constructor
+#ifdef XXX_STINSON_CHUI_REWORK
+ LLVoiceVisualizer( const U8 type ); //constructor
+#else // XXX_STINSON_CHUI_REWORK
+ LLVoiceVisualizer(); //constructor
+#endif // XXX_STINSON_CHUI_REWORK
~LLVoiceVisualizer(); //destructor
-
- friend class LLHUDObject;
+#ifdef XXX_STINSON_CHUI_REWORK
void setVoiceSourceWorldPosition( const LLVector3 &p ); // this should be the position of the speaking avatar's head
void setMinGesticulationAmplitude( F32 ); // the lower range of meaningful amplitude for setting gesticulation level
void setMaxGesticulationAmplitude( F32 ); // the upper range of meaningful amplitude for setting gesticulation level
+#endif // XXX_STINSON_CHUI_REWORK
void setStartSpeaking(); // tell me when the av starts speaking
+#ifdef XXX_STINSON_CHUI_REWORK
void setVoiceEnabled( bool ); // tell me whether or not the user is voice enabled
+#endif // XXX_STINSON_CHUI_REWORK
void setSpeakingAmplitude( F32 ); // tell me how loud the av is speaking (ranges from 0 to 1)
void setStopSpeaking(); // tell me when the av stops speaking
bool getCurrentlySpeaking(); // the get for the above set
VoiceGesticulationLevel getCurrentGesticulationLevel(); // based on voice amplitude, I'll give you the current "energy level" of avatar speech
- static void setPreferences( );
- static void lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s ); // convert a string of digits to an array of floats
void lipSyncOohAah( F32& ooh, F32& aah );
+#ifdef XXX_STINSON_CHUI_REWORK
void render(); // inherited from HUD Effect
void packData(LLMessageSystem *mesgsys); // inherited from HUD Effect
void unpackData(LLMessageSystem *mesgsys, S32 blocknum); // inherited from HUD Effect
@@ -103,12 +118,17 @@ class LLVoiceVisualizer : public LLHUDEffect
//----------------------------------------------------------------------------------------------
void setMaxGesticulationAmplitude();
void setMinGesticulationAmplitude();
+#endif // XXX_STINSON_CHUI_REWORK
//---------------------------------------------------
// private members
//---------------------------------------------------
private:
-
+ static bool handleVoiceVisualizerPrefsChanged(const LLSD& newvalue);
+ static void setPreferences( );
+ static void lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s ); // convert a string of digits to an array of floats
+
+#ifdef XXX_STINSON_CHUI_REWORK
struct SoundSymbol
{
F32 mWaveExpansion [ NUM_VOICE_SYMBOL_WAVES ];
@@ -119,15 +139,20 @@ class LLVoiceVisualizer : public LLHUDEffect
bool mActive;
LLVector3 mPosition;
};
+#endif // XXX_STINSON_CHUI_REWORK
LLFrameTimer mTimer; // so I can ask the current time in seconds
F64 mStartTime; // time in seconds when speaking started
+#ifdef XXX_STINSON_CHUI_REWORK
F64 mCurrentTime; // current time in seconds, captured every step
F64 mPreviousTime; // copy of "current time" from last frame
SoundSymbol mSoundSymbol; // the sound symbol that appears over the avatar's head
bool mVoiceEnabled; // if off, no rendering should happen
+#endif // XXX_STINSON_CHUI_REWORK
bool mCurrentlySpeaking; // is the user currently speaking?
+#ifdef XXX_STINSON_CHUI_REWORK
LLVector3 mVoiceSourceWorldPosition; // give this to me every step - I need it to update the sound symbol
+#endif // XXX_STINSON_CHUI_REWORK
F32 mSpeakingAmplitude; // this should be set as often as possible when the user is speaking
F32 mMaxGesticulationAmplitude; // this is the upper-limit of the envelope of detectable gesticulation leves
F32 mMinGesticulationAmplitude; // this is the lower-limit of the envelope of detectable gesticulation leves
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index a64655960f..6900a82ea8 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -4664,11 +4664,6 @@ void LLPipeline::rebuildPools()
}
max_count--;
}
-
- if (isAgentAvatarValid())
- {
- gAgentAvatarp->rebuildHUD();
- }
}
void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
@@ -6184,7 +6179,7 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable)
}
void LLPipeline::resetVertexBuffers()
-{
+{
mResetVertexBuffers = true;
}
diff --git a/indra/newview/skins/default/xui/en/floater_people.xml b/indra/newview/skins/default/xui/en/floater_people.xml
index d6d8431150..45afe6b70b 100644
--- a/indra/newview/skins/default/xui/en/floater_people.xml
+++ b/indra/newview/skins/default/xui/en/floater_people.xml
@@ -7,20 +7,20 @@
height="570"
help_topic="sidebar_people"
min_height="440"
- min_width="333"
+ min_width="390"
layout="topleft"
name="floater_people"
save_rect="true"
single_instance="true"
reuse_instance="true"
title="PEOPLE"
- width="333">
+ width="390">
<panel_container
default_panel_name="panel_people"
follows="all"
height="570"
name="main_panel"
- width="333">
+ width="390">
<panel
class="panel_people"
name="panel_people"
@@ -31,11 +31,5 @@
filename="panel_group_info_sidetray.xml"
label="Group Profile"
font="SansSerifBold"/>
- <panel
- class="panel_block_list_sidetray"
- name="panel_block_list_sidetray"
- filename="panel_block_list_sidetray.xml"
- label="Blocked Residents &amp; Objects"
- font="SansSerifBold"/>
</panel_container>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_voice_volume.xml b/indra/newview/skins/default/xui/en/floater_voice_volume.xml
new file mode 100644
index 0000000000..9346295d5b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_voice_volume.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!--
+ Not can_close / no title to avoid window chrome
+ Single instance - only have one at a time, recycle it each spawn
+-->
+<floater
+ legacy_header_height="25"
+ bevel_style="in"
+ bg_opaque_image="Inspector_Background"
+ can_close="false"
+ can_minimize="false"
+ height="90"
+ layout="topleft"
+ name="floater_voice_volume"
+ single_instance="true"
+ sound_flags="0"
+ title="VOICE VOLUME"
+ visible="true"
+ width="245">
+ <text
+ follows="top|left|right"
+ font="SansSerifSmall"
+ height="21"
+ left="10"
+ name="avatar_name"
+ parse_urls="false"
+ top="35"
+ text_color="White"
+ translate="false"
+ use_ellipses="true"
+ value="TestString PleaseIgnore"
+ width="225" />
+ <slider
+ follows="top|left"
+ height="23"
+ increment="0.01"
+ left="1"
+ max_val="0.95"
+ min_val="0.05"
+ name="volume_slider"
+ show_text="false"
+ tool_tip="Voice volume"
+ top_pad="0"
+ value="0.5"
+ width="200" />
+ <button
+ follows="top|left"
+ height="16"
+ image_disabled="Audio_Off"
+ image_disabled_selected="AudioMute_Off"
+ image_hover_selected="AudioMute_Over"
+ image_selected="AudioMute_Off"
+ image_unselected="Audio_Off"
+ is_toggle="true"
+ left_pad="0"
+ top_delta="4"
+ name="mute_btn"
+ width="16" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml
index bc3bcd331b..c3481e6d4c 100644
--- a/indra/newview/skins/default/xui/en/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml
@@ -9,7 +9,7 @@
bg_opaque_image="Inspector_Background"
can_close="false"
can_minimize="false"
- height="164"
+ height="130"
layout="topleft"
name="inspect_avatar"
single_instance="true"
@@ -94,32 +94,17 @@
use_ellipses="true"
width="220">This is my second life description and I really think it is great. But for some reason my description is super extra long because I like to talk a whole lot
</text>
- <slider
- follows="top|left"
- height="23"
- increment="0.01"
- left="1"
- max_val="0.95"
- min_val="0.05"
- name="volume_slider"
- show_text="false"
- tool_tip="Voice volume"
- top_pad="0"
- value="0.5"
- width="200" />
- <button
+ <text
follows="top|left"
height="16"
- image_disabled="Audio_Off"
- image_disabled_selected="AudioMute_Off"
- image_hover_selected="AudioMute_Over"
- image_selected="AudioMute_Off"
- image_unselected="Audio_Off"
- is_toggle="true"
- left_pad="0"
- top_delta="4"
- name="mute_btn"
- width="16" />
+ left="8"
+ name="avatar_profile_link"
+ font="SansSerifSmall"
+ text_color="White"
+ top_pad="5"
+ translate="false"
+ value="[[LINK] View full profile]"
+ width="175" />
<avatar_icon
follows="top|left"
height="38"
@@ -130,83 +115,4 @@
name="avatar_icon"
top="10"
width="38" />
-<!-- Overlapping buttons for default actions
- llinspectavatar.cpp makes visible the most likely default action
--->
- <button
- follows="top|left"
- height="20"
- label="Add Friend"
- left="8"
- top="135"
- name="add_friend_btn"
- width="90" />
- <button
- follows="top|left"
- height="20"
- label="IM"
- left_delta="0"
- top_delta="0"
- name="im_btn"
- width="80"
- commit_callback.function="InspectAvatar.IM"/>
- <button
- follows="top|left"
- height="20"
- label="Profile"
- layout="topleft"
- name="view_profile_btn"
- left_delta="96"
- top_delta="0"
- tab_stop="false"
- width="80" />
- <!-- gear buttons here -->
- <menu_button
- follows="top|left"
- height="20"
- layout="topleft"
- image_overlay="OptionsMenu_Off"
- menu_filename="menu_inspect_avatar_gear.xml"
- name="gear_btn"
- right="-5"
- top_delta="0"
- width="35" />
- <menu_button
- follows="top|left"
- height="20"
- image_overlay="OptionsMenu_Off"
- menu_filename="menu_inspect_self_gear.xml"
- name="gear_self_btn"
- right="-5"
- top_delta="0"
- width="35" />
- <panel
- follows="top|left"
- top="164"
- left="0"
- height="60"
- width="228"
- visible="false"
- background_visible="true"
- name="moderator_panel"
- background_opaque="true"
- bg_opaque_color="MouseGray">
- <button
- name="disable_voice"
- label="Disable Voice"
- top="20"
- width="95"
- height="20"
- left="10"
- commit_callback.function="InspectAvatar.DisableVoice"/>
- <button
- name="enable_voice"
- label="Enable Voice"
- top="20"
- width="95"
- height="20"
- left="10"
- visible="false"
- commit_callback.function="InspectAvatar.EnableVoice"/>
- </panel>
</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_group_plus.xml b/indra/newview/skins/default/xui/en/menu_group_plus.xml
index fce7414d80..eca9e7f3c9 100644
--- a/indra/newview/skins/default/xui/en/menu_group_plus.xml
+++ b/indra/newview/skins/default/xui/en/menu_group_plus.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<menu name="menu_group_plus"
+<toggleable_menu name="menu_group_plus"
left="0" bottom="0" visible="false"
mouse_opaque="false">
<menu_item_call name="item_join" label="Join Group...">
@@ -8,4 +8,4 @@
<menu_item_call name="item_new" label="New Group...">
<menu_item_call.on_click function="People.Group.Plus.Action" userdata="new_group" />
</menu_item_call>
-</menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml
deleted file mode 100644
index 76b188220d..0000000000
--- a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml
+++ /dev/null
@@ -1,143 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<toggleable_menu
- create_jump_keys="true"
- layout="topleft"
- mouse_opaque="false"
- visible="false"
- name="Gear Menu">
- <menu_item_call
- label="View Profile"
- enabled="true"
- name="view_profile">
- <menu_item_call.on_click
- function="InspectAvatar.ViewProfile"/>
- </menu_item_call>
- <menu_item_call
- label="Add Friend"
- name="add_friend">
- <menu_item_call.on_click
- function="InspectAvatar.AddFriend"/>
- <menu_item_call.on_enable
- function="InspectAvatar.Gear.Enable"/>
- </menu_item_call>
- <menu_item_call
- label="IM"
- name="im">
- <menu_item_call.on_click
- function="InspectAvatar.IM"/>
- </menu_item_call>
- <menu_item_call
- label="Call"
- enabled="true"
- name="call">
- <menu_item_call.on_click
- function="InspectAvatar.Call"/>
- <menu_item_call.on_enable
- function="InspectAvatar.Gear.EnableCall"/>
- </menu_item_call>
- <menu_item_call
- label="Teleport"
- name="teleport">
- <menu_item_call.on_click
- function="InspectAvatar.Teleport"/>
- <menu_item_call.on_enable
- function="InspectAvatar.Gear.EnableTeleportOffer"/>
- </menu_item_call>
- <menu_item_call
- label="Invite to Group"
- name="invite_to_group">
- <menu_item_call.on_click
- function="InspectAvatar.InviteToGroup"/>
- </menu_item_call>
- <menu_item_separator />
- <menu_item_call
- label="Block"
- name="block">
- <menu_item_call.on_click
- function="InspectAvatar.ToggleMute"/>
- <menu_item_call.on_visible
- function="InspectAvatar.EnableMute" />
- </menu_item_call>
- <menu_item_call
- label="Unblock"
- name="unblock">
- <menu_item_call.on_click
- function="InspectAvatar.ToggleMute"/>
- <menu_item_call.on_visible
- function="InspectAvatar.EnableUnmute" />
- </menu_item_call>
- <menu_item_call
- label="Report"
- name="report">
- <menu_item_call.on_click
- function="InspectAvatar.Report"/>
- </menu_item_call>
- <menu_item_call
- label="Freeze"
- name="freeze">
- <menu_item_call.on_click
- function="InspectAvatar.Freeze"/>
- <menu_item_call.on_visible
- function="InspectAvatar.VisibleFreeze"/>
- </menu_item_call>
- <menu_item_call
- label="Eject"
- name="eject">
- <menu_item_call.on_click
- function="InspectAvatar.Eject"/>
- <menu_item_call.on_visible
- function="InspectAvatar.VisibleEject"/>
- </menu_item_call>
- <menu_item_call
- label="Kick"
- name="kick">
- <menu_item_call.on_click
- function="InspectAvatar.Kick"/>
- <menu_item_call.on_visible
- function="InspectAvatar.EnableGod"/>
- </menu_item_call>
- <menu_item_call
- label="CSR"
- name="csr">
- <menu_item_call.on_click
- function="InspectAvatar.CSR" />
- <menu_item_call.on_visible
- function="InspectAvatar.EnableGod" />
- </menu_item_call>
- <menu_item_call
- label="Debug Textures"
- name="debug">
- <menu_item_call.on_click
- function="Avatar.Debug"/>
- <menu_item_call.on_visible
- function="IsGodCustomerService"/>
- </menu_item_call>
- <menu_item_call
- label="Find On Map"
- name="find_on_map">
- <menu_item_call.on_click
- function="InspectAvatar.FindOnMap"/>
- <menu_item_call.on_visible
- function="InspectAvatar.VisibleFindOnMap"/>
- </menu_item_call>
- <menu_item_call
- label="Zoom In"
- name="zoom_in">
- <menu_item_call.on_click
- function="InspectAvatar.ZoomIn"/>
- <menu_item_call.on_visible
- function="InspectAvatar.VisibleZoomIn"/>
- </menu_item_call>
- <menu_item_call
- label="Pay"
- name="pay">
- <menu_item_call.on_click
- function="InspectAvatar.Pay"/>
- </menu_item_call>
- <menu_item_call
- label="Share"
- name="share">
- <menu_item_call.on_click
- function="InspectAvatar.Share"/>
- </menu_item_call>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml
deleted file mode 100644
index 5e7b16ed4a..0000000000
--- a/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml
+++ /dev/null
@@ -1,252 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<toggleable_menu
- layout="topleft"
- name="Self Pie">
- <menu_item_call
- label="Sit Down"
- layout="topleft"
- name="Sit Down Here">
- <menu_item_call.on_click
- function="Self.SitDown"
- parameter="" />
- <menu_item_call.on_enable
- function="Self.EnableSitDown" />
- </menu_item_call>
- <menu_item_call
- label="Stand Up"
- layout="topleft"
- name="Stand Up">
- <menu_item_call.on_click
- function="Self.StandUp"
- parameter="" />
- <menu_item_call.on_enable
- function="Self.EnableStandUp" />
- </menu_item_call>
- <context_menu
- label="Take Off"
- layout="topleft"
- name="Take Off &gt;">
- <context_menu
- label="Clothes"
- layout="topleft"
- name="Clothes &gt;">
- <menu_item_call
- enabled="false"
- label="Shirt"
- layout="topleft"
- name="Shirt">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="shirt" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="shirt" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Pants"
- layout="topleft"
- name="Pants">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="pants" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="pants" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Skirt"
- layout="topleft"
- name="Skirt">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="skirt" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="skirt" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Shoes"
- layout="topleft"
- name="Shoes">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="shoes" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="shoes" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Socks"
- layout="topleft"
- name="Socks">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="socks" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="socks" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Jacket"
- layout="topleft"
- name="Jacket">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="jacket" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="jacket" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Gloves"
- layout="topleft"
- name="Gloves">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="gloves" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="gloves" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Undershirt"
- layout="topleft"
- name="Self Undershirt">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="undershirt" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="undershirt" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Underpants"
- layout="topleft"
- name="Self Underpants">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="underpants" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="underpants" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Tattoo"
- layout="topleft"
- name="Self Tattoo">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="tattoo" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="tattoo" />
- </menu_item_call>
- <menu_item_call
- enabled="false"
- label="Alpha"
- layout="topleft"
- name="Self Alpha">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="alpha" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="alpha" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="All Clothes"
- layout="topleft"
- name="All Clothes">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="all" />
- </menu_item_call>
- </context_menu>
- <context_menu
- label="HUD"
- layout="topleft"
- name="Object Detach HUD" />
- <context_menu
- label="Detach"
- layout="topleft"
- name="Object Detach" />
- <menu_item_call
- label="Detach All"
- layout="topleft"
- name="Detach All">
- <menu_item_call.on_click
- function="Self.RemoveAllAttachments"
- parameter="" />
- <menu_item_call.on_enable
- function="Self.EnableRemoveAllAttachments" />
- </menu_item_call>
- </context_menu>
- <menu_item_call
- label="Change Outfit"
- layout="topleft"
- name="Chenge Outfit">
- <menu_item_call.on_click
- function="CustomizeAvatar" />
- <menu_item_call.on_enable
- function="Edit.EnableCustomizeAvatar" />
- </menu_item_call>
- <menu_item_call label="Edit My Outfit"
- layout="topleft"
- name="Edit Outfit">
- <menu_item_call.on_click
- function="EditOutfit" />
- <menu_item_call.on_enable
- function="Edit.EnableCustomizeAvatar" />
- </menu_item_call>
- <menu_item_call label="Edit My Shape"
- layout="topleft"
- name="Edit My Shape">
- <menu_item_call.on_click
- function="EditShape" />
- <menu_item_call.on_enable
- function="Edit.EnableEditShape" />
- </menu_item_call>
- <menu_item_call
- label="My Friends"
- layout="topleft"
- name="Friends...">
- <menu_item_call.on_click
- function="SideTray.PanelPeopleTab"
- parameter="friends_panel" />
- </menu_item_call>
- <menu_item_call
- label="My Groups"
- layout="topleft"
- name="Groups...">
- <menu_item_call.on_click
- function="SideTray.PanelPeopleTab"
- parameter="groups_panel" />
- </menu_item_call>
- <menu_item_call
- label="My Profile"
- layout="topleft"
- name="Profile...">
- <menu_item_call.on_click
- function="ShowAgentProfile"
- parameter="agent" />
- </menu_item_call>
- <menu_item_call
- label="Debug Textures"
- name="Debug...">
- <menu_item_call.on_click
- function="Avatar.Debug" />
- <menu_item_call.on_visible
- function="IsGodCustomerService"/>
- </menu_item_call>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
index b452f96e7a..eab7b8c085 100644
--- a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
@@ -40,8 +40,4 @@
function="CheckControl"
parameter="FriendsListShowPermissions" />
</menu_item_check>
- <menu_item_separator layout="topleft" />
- <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
- <menu_item_call.on_click function="People.Friends.ViewSort.Action" parameter="panel_block_list_sidetray" />
- </menu_item_call>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_groups.xml b/indra/newview/skins/default/xui/en/menu_people_groups.xml
index 8f89d37dbb..3a450258fa 100644
--- a/indra/newview/skins/default/xui/en/menu_people_groups.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_groups.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<menu name="menu_group_plus"
+<toggleable_menu name="menu_group_plus"
left="0" bottom="0" visible="false"
mouse_opaque="false" opaque="true" color="MenuDefaultBgColor">
<menu_item_call
@@ -54,4 +54,4 @@
function="People.Groups.Enable"
parameter="leave" />
</menu_item_call>
-</menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_groups_view.xml
index c710fe3b9b..73f79f1e70 100644
--- a/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_groups_view.xml
@@ -14,13 +14,4 @@
function="CheckControl"
parameter="GroupListShowIcons" />
</menu_item_check>
- <menu_item_call
- label="Leave Selected Group"
- layout="topleft"
- name="Leave Selected Group">
- <menu_item_call.on_click
- function="People.Group.Minus.Action"/>
- <menu_item_call.on_enable
- function="People.Group.Minus.Enable"/>
- </menu_item_call>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml
new file mode 100644
index 0000000000..da88ca9f4d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ name="menu_group_plus"
+ left="0" bottom="0" visible="false"
+ mouse_opaque="false">
+ <menu_item_check
+ label="Sort by Recent Speakers"
+ name="sort_by_recent_speakers">
+ <menu_item_check.on_click
+ function="People.Nearby.ViewSort.Action"
+ parameter="sort_by_recent_speakers"/>
+ <menu_item_check.on_check
+ function="People.Nearby.ViewSort.CheckItem"
+ parameter="sort_by_recent_speakers"/>
+ </menu_item_check>
+ <menu_item_check
+ label="Sort by Name"
+ name="sort_name">
+ <menu_item_check.on_click
+ function="People.Nearby.ViewSort.Action"
+ parameter="sort_name"/>
+ <menu_item_check.on_check
+ function="People.Nearby.ViewSort.CheckItem"
+ parameter="sort_name"/>
+ </menu_item_check>
+ <menu_item_check
+ label="Sort by Distance"
+ name="sort_distance">
+ <menu_item_check.on_click
+ function="People.Nearby.ViewSort.Action"
+ parameter="sort_distance"/>
+ <menu_item_check.on_check
+ function="People.Nearby.ViewSort.CheckItem"
+ parameter="sort_distance"/>
+ </menu_item_check>
+ <menu_item_separator layout="topleft" />
+ <menu_item_check name="view_icons" label="View People Icons">
+ <menu_item_check.on_click
+ function="People.Nearby.ViewSort.Action"
+ parameter="view_icons" />
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="NearbyListShowIcons" />
+ </menu_item_check>
+ <menu_item_check name ="view_map" label="View Map">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="NearbyListShowMap" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="NearbyListShowMap" />
+ </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml
deleted file mode 100644
index 614dd693c5..0000000000
--- a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<toggleable_menu
- name="menu_group_plus"
- left="0" bottom="0" visible="false"
- mouse_opaque="false">
- <menu_item_check
- label="Sort by Recent Speakers"
- name="sort_by_recent_speakers">
- <menu_item_check.on_click
- function="People.Nearby.ViewSort.Action"
- parameter="sort_by_recent_speakers"/>
- <menu_item_check.on_check
- function="People.Nearby.ViewSort.CheckItem"
- parameter="sort_by_recent_speakers"/>
- </menu_item_check>
- <menu_item_check
- label="Sort by Name"
- name="sort_name">
- <menu_item_check.on_click
- function="People.Nearby.ViewSort.Action"
- parameter="sort_name"/>
- <menu_item_check.on_check
- function="People.Nearby.ViewSort.CheckItem"
- parameter="sort_name"/>
- </menu_item_check>
- <menu_item_check
- label="Sort by Distance"
- name="sort_distance">
- <menu_item_check.on_click
- function="People.Nearby.ViewSort.Action"
- parameter="sort_distance"/>
- <menu_item_check.on_check
- function="People.Nearby.ViewSort.CheckItem"
- parameter="sort_distance"/>
- </menu_item_check>
- <menu_item_separator layout="topleft" />
- <menu_item_check name="view_icons" label="View People Icons">
- <menu_item_check.on_click
- function="People.Nearby.ViewSort.Action"
- parameter="view_icons" />
- <menu_item_check.on_check
- function="CheckControl"
- parameter="NearbyListShowIcons" />
- </menu_item_check>
- <menu_item_check name ="view_map" label="View Map">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="NearbyListShowMap" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="NearbyListShowMap" />
- </menu_item_check>
- <menu_item_separator layout="topleft" />
- <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
- <menu_item_call.on_click function="People.Nearby.ViewSort.Action" userdata="panel_block_list_sidetray" />
- </menu_item_call>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_recent_view.xml
index 485a5a658c..1dbc90dd2b 100644
--- a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_recent_view.xml
@@ -32,8 +32,4 @@
function="CheckControl"
parameter="RecentListShowIcons" />
</menu_item_check>
- <menu_item_separator layout="topleft" />
- <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
- <menu_item_call.on_click function="People.Recent.ViewSort.Action" userdata="panel_block_list_sidetray" />
- </menu_item_call>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 59dd17ea9d..d35cebbd16 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -2904,6 +2904,7 @@ Would you like to trust this authority?
icon="alertmodal.tga"
name="GrantedModifyRights"
persist="true"
+ log_to_im="true"
type="notify">
[NAME] has given you permission to edit their objects.
</notification>
@@ -2912,6 +2913,7 @@ Would you like to trust this authority?
icon="alertmodal.tga"
name="RevokedModifyRights"
persist="true"
+ log_to_im="true"
type="notify">
Your privilege to modify [NAME]&apos;s objects has been revoked
</notification>
@@ -5161,6 +5163,8 @@ The string [STRING_NAME] is missing from strings.xml
<notification
icon="notifytip.tga"
name="IMSystemMessageTip"
+ log_to_im="true"
+ log_to_chat="false"
type="notifytip">
[MESSAGE]
</notification>
@@ -5205,6 +5209,7 @@ Topic: [SUBJECT], Message: [MESSAGE]
<notification
icon="notifytip.tga"
name="FriendOnline"
+ log_to_chat="false"
type="notifytip">
<tag>friendship</tag>
&lt;nolink&gt;[NAME]&lt;/nolink&gt; is Online
@@ -5213,6 +5218,7 @@ Topic: [SUBJECT], Message: [MESSAGE]
<notification
icon="notifytip.tga"
name="FriendOffline"
+ log_to_chat="false"
type="notifytip">
<tag>friendship</tag>
&lt;nolink&gt;[NAME]&lt;/nolink&gt; is Offline
@@ -5459,6 +5465,8 @@ You don&apos;t have permission to copy this.
<notification
icon="notifytip.tga"
name="InventoryAccepted"
+ log_to_im="true"
+ log_to_chat="false"
type="notifytip">
[NAME] received your inventory offer.
</notification>
@@ -5466,6 +5474,8 @@ You don&apos;t have permission to copy this.
<notification
icon="notifytip.tga"
name="InventoryDeclined"
+ log_to_im="true"
+ log_to_chat="false"
type="notifytip">
[NAME] declined your inventory offer.
</notification>
@@ -5547,6 +5557,7 @@ Please select at least one type of content to search (General, Moderate, or Adul
<notification
icon="notify.tga"
name="PaymentReceived"
+ log_to_im="true"
persist="true"
type="notify">
<tag>funds</tag>
@@ -5556,6 +5567,7 @@ Please select at least one type of content to search (General, Moderate, or Adul
<notification
icon="notify.tga"
name="PaymentSent"
+ log_to_im="true"
persist="true"
type="notify">
<tag>funds</tag>
@@ -5700,6 +5712,7 @@ The objects on the selected parcel that are NOT owned by you have been returned
<notification
icon="notify.tga"
name="ServerObjectMessage"
+ log_to_im="true"
persist="true"
type="notify">
Message from [NAME]:
@@ -6070,6 +6083,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
<notification
icon="notify.tga"
name="UserGiveItem"
+ log_to_im ="true"
type="offer">
[NAME_SLURL] has given you this [OBJECTTYPE]:
[ITEM_SLURL]
@@ -6125,6 +6139,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
<notification
icon="notify.tga"
name="TeleportOffered"
+ log_to_im="true"
type="offer">
[NAME_SLURL] has offered to teleport you to their location:
@@ -6145,6 +6160,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
<notification
icon="notify.tga"
name="TeleportOfferSent"
+ log_to_im="true"
type="offer">
Teleport offer sent to [TO_NAME]
</notification>
@@ -6172,6 +6188,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
<notification
icon="notify.tga"
name="OfferFriendship"
+ log_to_im="true"
type="offer">
<tag>friendship</tag>
<tag>confirm</tag>
@@ -6195,6 +6212,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
<notification
icon="notify.tga"
name="FriendshipOffered"
+ log_to_im="true"
type="offer">
<tag>friendship</tag>
You have offered friendship to [TO_NAME]
@@ -6224,6 +6242,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
<notification
icon="notify.tga"
name="FriendshipAccepted"
+ log_to_im="true"
type="offer">
<tag>friendship</tag>
&lt;nolink&gt;[NAME]&lt;/nolink&gt; accepted your friendship offer.
@@ -6232,6 +6251,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
<notification
icon="notify.tga"
name="FriendshipDeclined"
+ log_to_im="true"
persist="true"
type="notify">
<tag>friendship</tag>
@@ -6241,6 +6261,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
<notification
icon="notify.tga"
name="FriendshipAcceptedByMe"
+ log_to_im="true"
type="offer">
<tag>friendship</tag>
Friendship offer accepted.
@@ -6249,6 +6270,7 @@ Friendship offer accepted.
<notification
icon="notify.tga"
name="FriendshipDeclinedByMe"
+ log_to_im="true"
type="offer">
<tag>friendship</tag>
Friendship offer declined.
diff --git a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
index 7c67fd7f83..3577d2f457 100644
--- a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
@@ -4,6 +4,8 @@
follows="left|top|right|bottom"
height="305"
layout="topleft"
+ left="0"
+ right="-1"
name="block_list_panel"
help_topic="blocked_list"
min_height="350"
@@ -28,7 +30,7 @@
layout="topleft"
left_pad="10"
name="title_text"
- text_color="White"
+ text_color="white"
top="5"
width="250">
Block List
@@ -41,6 +43,7 @@
name="blocked"
tool_tip="List of currently blocked Residents"
top="30"
+ right="-1"
width="270">
<scroll_list.columns
name="item_name" />
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 98c7c49ff4..abfb9c7a36 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -38,12 +38,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
name="no_filtered_friends_msg">
Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search].
</string>
- <string
- name="people_filter_label"
- value="Filter People" />
- <string
- name="groups_filter_label"
- value="Filter Groups" />
<!--
*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
@@ -60,21 +54,9 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
<string
name="AltMiniMapToolTipMsg"
value="[REGION](Double-click to teleport, shift-drag to pan)"/>
- <filter_editor
- follows="left|top|right"
- height="23"
- layout="topleft"
- left="10"
- label="Filter"
- max_length_chars="300"
- name="filter_input"
- text_color="Black"
- text_pad_left="10"
- top="3"
- width="303" />
<tab_container
+ bottom="-10"
follows="all"
- height="383"
layout="topleft"
left="3"
name="tabs"
@@ -82,31 +64,116 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
tab_min_width="70"
tab_height="30"
tab_position="top"
- top_pad="10"
+ top="0"
halign="center"
- width="319">
- <panel
+ right="-5">
+
+<!-- ================================= NEARBY tab =========================== -->
+
+ <panel
background_opaque="true"
background_visible="true"
bg_alpha_color="DkGray"
bg_opaque_color="DkGray"
+ bottom="-1"
follows="all"
- height="383"
label="NEARBY"
layout="topleft"
left="0"
help_topic="people_nearby_tab"
name="nearby_panel"
- top="0"
- width="313">
+ right="-1"
+ top="0">
+ <panel
+ follows="left|top|right"
+ height="27"
+ label="bottom_panel"
+ layout="topleft"
+ left="0"
+ name="nearby_buttons_panel"
+ right="-1"
+ top="0">
+ <filter_editor
+ follows="left|top|right"
+ height="23"
+ layout="topleft"
+ left="6"
+ label="Filter People"
+ max_length_chars="300"
+ name="nearby_filter_input"
+ text_color="Black"
+ text_pad_left="10"
+ top="4"
+ width="178" />
+ <button
+ commit_callback.function="People.Gear"
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="OptionsMenu_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="7"
+ name="gear_btn"
+ top="3"
+ width="31" />
+ <menu_button
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Inv_Underpants"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="2"
+ menu_filename="menu_people_nearby_view.xml"
+ menu_position="bottomleft"
+ name="nearby_view_btn"
+ top_delta="0"
+ width="31" />
+ <button
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="AddItem_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="2"
+ name="add_friend_btn"
+ top_delta="0"
+ width="31">
+ <commit_callback
+ function="People.AddFriend" />
+ </button>
+ <dnd_button
+ enabled="false"
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="TrashItem_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ left_pad="2"
+ layout="topleft"
+ name="nearby_del_btn"
+ top_delta="0"
+ width="31">
+ <commit_callback
+ function="People.DelFriend" />
+ </dnd_button>
+ </panel>
<layout_stack
clip="false"
follows="all"
- height="355"
+ height="410"
layout="topleft"
+ left="0"
mouse_opaque="false"
orientation="vertical"
- width="313">
+ right="-1"
+ top_pad="0">
<layout_panel
height="142"
layout="topleft"
@@ -123,16 +190,16 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
left="3"
mouse_opaque="false"
name="Net Map"
- top="4"
- width="305"/>
+ right="-1"
+ top="4" />
</layout_panel>
<layout_panel
height="213"
layout="topleft"
min_dim="100"
mouse_opaque="false"
- user_resize="true"
- width="313">
+ right="-1"
+ user_resize="true">
<avatar_list
allow_select="true"
follows="all"
@@ -143,84 +210,118 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
keep_one_selected="false"
multi_select="true"
name="avatar_list"
- top="2"
- width="306" />
+ right="-1"
+ top="2" />
</layout_panel>
</layout_stack>
- <panel
- background_visible="true"
- follows="left|right|bottom"
- height="27"
- label="bottom_panel"
- layout="topleft"
- left="3"
- name="bottom_panel"
- top_pad="0"
- width="313">
- <menu_button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Left_Over"
- image_overlay="OptionsMenu_Off"
- image_selected="Toolbar_Left_Selected"
- image_unselected="Toolbar_Left_Off"
- layout="topleft"
- left="0"
- name="nearby_view_sort_btn"
- tool_tip="Options"
- top="1"
- width="31" />
- <button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Middle_Over"
- image_overlay="AddItem_Off"
- image_selected="Toolbar_Middle_Selected"
- image_unselected="Toolbar_Middle_Off"
- layout="topleft"
- left_pad="1"
- name="add_friend_btn"
- tool_tip="Add selected Resident to your friends List"
- width="31">
- <commit_callback
- function="People.addFriend" />
- </button>
- <icon
- follows="bottom|left|right"
- height="25"
- image_name="Toolbar_Right_Off"
- layout="topleft"
- left_pad="1"
- name="dummy_icon"
- width="243"
- />
- </panel>
</panel>
+
+<!-- ================================= FRIENDS tab ========================== -->
+
<panel
background_opaque="true"
background_visible="true"
bg_alpha_color="DkGray"
bg_opaque_color="DkGray"
+ bottom="-1"
follows="all"
- height="383"
label="MY FRIENDS"
layout="topleft"
left="0"
help_topic="people_friends_tab"
name="friends_panel"
- top="0"
- width="313">
+ right="-1"
+ top="0">
+ <panel
+ follows="left|top|right"
+ height="27"
+ label="bottom_panel"
+ layout="topleft"
+ left="0"
+ name="friends_buttons_panel"
+ right="-1"
+ top="0">
+ <filter_editor
+ follows="left|top|right"
+ height="23"
+ layout="topleft"
+ left="6"
+ label="Filter People"
+ max_length_chars="300"
+ name="friends_filter_input"
+ text_color="Black"
+ text_pad_left="10"
+ top="4"
+ width="177" />
+ <button
+ commit_callback.function="People.Gear"
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="OptionsMenu_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="8"
+ name="gear_btn"
+ top="3"
+ width="31" />
+ <menu_button
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Inv_Underpants"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="2"
+ menu_filename="menu_people_friends_view.xml"
+ menu_position="bottomleft"
+ name="friends_view_btn"
+ top_delta="0"
+ width="31" />
+ <button
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="AddItem_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="2"
+ name="friends_add_btn"
+ top_delta="0"
+ width="31">
+ <commit_callback
+ function="People.AddFriendWizard" />
+ </button>
+ <dnd_button
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="TrashItem_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ left_pad="2"
+ layout="topleft"
+ name="friends_del_btn"
+ top_delta="0"
+ width="31">
+ <commit_callback
+ function="People.DelFriend" />
+ </dnd_button>
+ </panel>
<accordion
background_visible="true"
bg_alpha_color="DkGray2"
bg_opaque_color="DkGray2"
follows="all"
- height="356"
+ height="408"
layout="topleft"
left="3"
name="friends_accordion"
- top="0"
- width="307">
+ right="-2"
+ top_pad="2">
<accordion_tab
layout="topleft"
height="172"
@@ -257,247 +358,131 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
width="307" />
</accordion_tab>
</accordion>
- <panel
- background_visible="true"
- follows="left|right|bottom"
- height="27"
- label="bottom_panel"
- layout="topleft"
- left="3"
- name="bottom_panel"
- top_pad="0"
- width="313">
-
- <layout_stack
- animate="false"
- border_size="0"
- follows="left|right|bottom"
- height="25"
- layout="topleft"
- orientation="horizontal"
- top_pad="1"
- left="0"
- name="bottom_panel"
- width="308">
- <layout_panel
- auto_resize="false"
- height="25"
- layout="topleft"
- name="options_gear_btn_panel"
- width="32">
- <menu_button
- follows="bottom|left"
- tool_tip="Show additional options"
- height="25"
- image_hover_unselected="Toolbar_Left_Over"
- image_overlay="OptionsMenu_Off"
- image_selected="Toolbar_Left_Selected"
- image_unselected="Toolbar_Left_Off"
- layout="topleft"
- left="0"
- name="friends_viewsort_btn"
- top="0"
- width="31" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- height="25"
- layout="topleft"
- name="add_btn_panel"
- width="32">
- <button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Middle_Over"
- image_overlay="AddItem_Off"
- image_selected="Toolbar_Middle_Selected"
- image_unselected="Toolbar_Middle_Off"
- layout="topleft"
- left="0"
- name="add_btn"
- tool_tip="Offer friendship to a Resident"
- top="0"
- width="31" />
- </layout_panel>
- <layout_panel
- auto_resize="true"
- height="25"
- layout="topleft"
- name="dummy_panel"
- width="210">
- <icon
- follows="bottom|left|right"
- height="25"
- image_name="Toolbar_Middle_Off"
- layout="topleft"
- left="0"
- top="0"
- name="dummy_icon"
- width="210" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- height="25"
- layout="topleft"
- name="trash_btn_panel"
- width="31">
- <dnd_button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Right_Over"
- image_overlay="TrashItem_Off"
- image_selected="Toolbar_Right_Selected"
- image_unselected="Toolbar_Right_Off"
- left="0"
- layout="topleft"
- name="del_btn"
- tool_tip="Remove selected person from your Friends list"
- top="0"
- width="31"/>
- </layout_panel>
- </layout_stack><!--
-
- <button
- follows="bottom|left"
- tool_tip="Options"
- height="25"
- image_hover_unselected="Toolbar_Left_Over"
- image_overlay="OptionsMenu_Off"
- image_selected="Toolbar_Left_Selected"
- image_unselected="Toolbar_Left_Off"
- layout="topleft"
- left="0"
- name="friends_viewsort_btn"
- top="1"
- width="31" />
- <button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Middle_Over"
- image_overlay="AddItem_Off"
- image_selected="Toolbar_Middle_Selected"
- image_unselected="Toolbar_Middle_Off"
- layout="topleft"
- left_pad="1"
- name="add_btn"
- tool_tip="Offer friendship to a Resident"
- width="31" />
- <icon
- follows="bottom|left|right"
- height="25"
- image_name="Toolbar_Middle_Off"
- layout="topleft"
- left_pad="1"
- name="dummy_icon"
- width="209"
- />
- <button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Right_Over"
- image_overlay="TrashItem_Off"
- image_selected="Toolbar_Right_Selected"
- image_unselected="Toolbar_Right_Off"
- layout="topleft"
- left_pad="1"
- name="del_btn"
- tool_tip="Remove selected person from your Friends list"
- width="31" />
- --></panel>
<text
follows="all"
height="450"
left="13"
name="no_friends_help_text"
- top="10"
- width="293"
+ right="-13"
+ top="37"
wrap="true" />
</panel>
+
+<!-- ================================= GROUPS tab =========================== -->
+
<panel
background_opaque="true"
background_visible="true"
bg_alpha_color="DkGray"
bg_opaque_color="DkGray"
+ bottom="-1"
follows="all"
- height="383"
label="MY GROUPS"
layout="topleft"
left="0"
help_topic="people_groups_tab"
name="groups_panel"
- top="0"
- width="313">
+ right="-1"
+ top="0">
<!--
*NOTE: no_groups_msg & group_list attributes are not defined as translatable in VLT. See EXT-5931
Values are set from appropriate strings at the top of file via LLPeoplePanel::postBuild()
-->
- <group_list
- allow_select="true"
- follows="all"
- height="356"
- layout="topleft"
- left="3"
- name="group_list"
- top="0"
- width="307" />
<panel
- background_visible="true"
- follows="left|right|bottom"
+ follows="left|top|right"
height="27"
label="bottom_panel"
layout="topleft"
left="0"
- name="bottom_panel"
- top_pad="0"
- width="313">
- <menu_button
- follows="bottom|left"
- tool_tip="Options"
- height="25"
- image_hover_unselected="Toolbar_Left_Over"
- image_overlay="OptionsMenu_Off"
- image_selected="Toolbar_Left_Selected"
- image_unselected="Toolbar_Left_Off"
- layout="topleft"
- left="3"
- name="groups_viewsort_btn"
- top="1"
- width="31" />
- <button
- follows="bottom|left"
+ name="groups_buttons_panel"
+ right="-1"
+ top="0">
+ <filter_editor
+ follows="left|top|right"
+ height="23"
+ layout="topleft"
+ left="6"
+ label="Filter Groups"
+ max_length_chars="300"
+ name="groups_filter_input"
+ text_color="Black"
+ text_pad_left="10"
+ top="4"
+ width="177" />
+ <menu_button
+ follows="right"
height="25"
image_hover_unselected="Toolbar_Middle_Over"
- image_overlay="AddItem_Off"
+ image_overlay="OptionsMenu_Off"
image_selected="Toolbar_Middle_Selected"
image_unselected="Toolbar_Middle_Off"
layout="topleft"
- left_pad="1"
- name="plus_btn"
- tool_tip="Join group/Create new group"
+ left_pad="8"
+ menu_filename="menu_people_groups.xml"
+ menu_position="bottomleft"
+ name="groups_gear_btn"
+ top="3"
width="31" />
- <button
- follows="bottom|left"
+ <menu_button
+ follows="right"
height="25"
image_hover_unselected="Toolbar_Middle_Over"
- image_overlay="Activate_Checkmark"
+ image_overlay="Inv_Underpants"
image_selected="Toolbar_Middle_Selected"
image_unselected="Toolbar_Middle_Off"
layout="topleft"
- left_pad="1"
- name="activate_btn"
- tool_tip="Activate selected group"
+ left_pad="2"
+ menu_filename="menu_people_groups_view.xml"
+ menu_position="bottomleft"
+ name="groups_view_btn"
+ top_delta="0"
width="31" />
- <icon
- follows="bottom|left|right"
- height="25"
- image_name="Toolbar_Right_Off"
- layout="topleft"
- left_pad="1"
- name="dummy_icon"
- width="212"
- />
+ <menu_button
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="AddItem_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="2"
+ menu_filename="menu_group_plus.xml"
+ menu_position="bottomleft"
+ name="plus_btn"
+ top_delta="0"
+ width="31">
+ <validate_callback
+ function="People.Group.Plus.Validate" />
+ </menu_button>
+ <dnd_button
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="TrashItem_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ left_pad="2"
+ layout="topleft"
+ name="minus_btn"
+ top_delta="0"
+ width="31">
+ <commit_callback
+ function="People.Group.Minus" />
+ </dnd_button>
</panel>
+ <group_list
+ allow_select="true"
+ follows="all"
+ height="406"
+ layout="topleft"
+ left="3"
+ name="group_list"
+ right="-2"
+ top_pad="4" />
</panel>
+
+<!-- ================================= RECENT tab =========================== -->
+
<panel
background_opaque="true"
background_visible="true"
@@ -510,265 +495,128 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
left="0"
help_topic="people_recent_tab"
name="recent_panel"
- top="0"
- width="313">
- <avatar_list
- allow_select="true"
- follows="all"
- height="356"
- layout="topleft"
- left="3"
- multi_select="true"
- name="avatar_list"
- show_last_interaction_time="true"
- top="0"
- width="307" />
+ right="-1"
+ top="0">
<panel
- background_visible="true"
- follows="left|right|bottom"
+ follows="left|top|right"
height="27"
label="bottom_panel"
layout="topleft"
- left="3"
- name="bottom_panel"
- top_pad="0"
- width="313">
- <menu_button
- follows="bottom|left"
- tool_tip="Options"
- height="25"
- image_hover_unselected="Toolbar_Left_Over"
- image_overlay="OptionsMenu_Off"
- image_selected="Toolbar_Left_Selected"
- image_unselected="Toolbar_Left_Off"
- layout="topleft"
- name="recent_viewsort_btn"
- top="1"
- width="31" />
- <button
- follows="bottom|left"
+ left="0"
+ name="recent_buttons_panel"
+ right="-1"
+ top="0">
+ <filter_editor
+ follows="left|top|right"
+ height="23"
+ layout="topleft"
+ left="6"
+ label="Filter People"
+ max_length_chars="300"
+ name="recent_filter_input"
+ text_color="Black"
+ text_pad_left="10"
+ top="4"
+ width="177" />
+ <button
+ commit_callback.function="People.Gear"
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="OptionsMenu_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="8"
+ name="gear_btn"
+ top="3"
+ width="31" />
+ <menu_button
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Inv_Underpants"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="2"
+ menu_filename="menu_people_recent_view.xml"
+ menu_position="bottomleft"
+ name="recent_view_btn"
+ top_delta="0"
+ width="31" />
+ <button
+ follows="right"
height="25"
image_hover_unselected="Toolbar_Middle_Over"
image_overlay="AddItem_Off"
image_selected="Toolbar_Middle_Selected"
image_unselected="Toolbar_Middle_Off"
layout="topleft"
- left_pad="1"
+ left_pad="2"
name="add_friend_btn"
- tool_tip="Add selected Resident to your friends List"
+ top_delta="0"
+ width="31">
+ <commit_callback
+ function="People.AddFriend" />
+ </button>
+ <dnd_button
+ enabled="false"
+ follows="right"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="TrashItem_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ left_pad="2"
+ layout="topleft"
+ name="recent_del_btn"
+ top_delta="0"
width="31">
- <commit_callback
- function="People.addFriend" />
- </button>
- <icon
- follows="bottom|left|right"
- height="25"
- image_name="Toolbar_Right_Off"
- layout="topleft"
- left_pad="1"
- name="dummy_icon"
- width="244"
- />
+ <commit_callback
+ function="People.DelFriend" />
+ </dnd_button>
</panel>
+ <avatar_list
+ allow_select="true"
+ follows="all"
+ height="351"
+ layout="topleft"
+ left="3"
+ multi_select="true"
+ name="avatar_list"
+ show_last_interaction_time="true"
+ right="-2"
+ top_pad="4" />
</panel>
- </tab_container>
- <panel
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- left="8"
- top_pad="4"
- name="button_bar"
- width="313">
-<!--********************************Profile; IM; Call, Share, Teleport********************************-->
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- name="bottom_bar_ls"
- left="0"
- orientation="horizontal"
- top_pad="0"
- width="313">
+<!-- ================================= BLOCKED tab ========================== -->
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left="0"
- name="view_profile_btn_lp"
- auto_resize="true"
- width="68">
- <button
- follows="bottom|left|right"
- height="23"
- label="Profile"
- layout="topleft"
- left="1"
- name="view_profile_btn"
- tool_tip="Show picture, groups, and other Residents information"
- top="0"
- width="67" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="im_btn_lp"
- auto_resize="true"
- width="41">
- <button
- follows="bottom|left|right"
- left="1"
- height="23"
- label="IM"
- layout="topleft"
- name="im_btn"
- tool_tip="Open instant message session"
- top="0"
- width="40" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="call_btn_lp"
- auto_resize="true"
- width="52">
- <button
- follows="bottom|left|right"
- left="1"
- height="23"
- label="Call"
- layout="topleft"
- name="call_btn"
- tool_tip="Call this Resident"
- top="0"
- width="51" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="share_btn_lp"
- auto_resize="true"
- width="66">
- <button
- follows="bottom|left|right"
- left="1"
- height="23"
- label="Share"
- layout="topleft"
- name="share_btn"
- tool_tip="Share an inventory item"
- top="0"
- width="65" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="teleport_btn_lp"
- auto_resize="true"
- width="77">
- <button
- follows="bottom|left|right"
- left="1"
- height="23"
- label="Teleport"
- layout="topleft"
- name="teleport_btn"
- tool_tip="Offer teleport"
- top="0"
- width="76" />
- </layout_panel>
- </layout_stack>
-
-<!--********************************Group Profile; Group Chat; Group Call buttons************************-->
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- mouse_opaque="false"
- name="bottom_bar_ls1"
- left="0"
- orientation="horizontal"
- top="0"
- width="313">
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left="0"
- mouse_opaque="false"
- name="group_info_btn_lp"
- auto_resize="true"
- width="108">
- <button
- follows="bottom|left|right"
- left="1"
- height="23"
- label="Group Profile"
- layout="topleft"
- mouse_opaque="false"
- name="group_info_btn"
- tool_tip="Show group information"
- top="0"
- width="107" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- mouse_opaque="false"
- name="chat_btn_lp"
- auto_resize="true"
- width="101">
- <button
- follows="bottom|left|right"
- left="1"
- height="23"
- label="Group Chat"
- layout="topleft"
- mouse_opaque="false"
- name="chat_btn"
- tool_tip="Open chat session"
- top="0"
- width="100" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- mouse_opaque="false"
- name="group_call_btn_lp"
- auto_resize="true"
- width="96">
- <button
- follows="bottom|left|right"
- left="1"
- height="23"
- label="Group Call"
- layout="topleft"
- mouse_opaque="false"
- name="group_call_btn"
- tool_tip="Call this group"
- top="0"
- width="95" />
- </layout_panel>
- </layout_stack>
- </panel>
+ <panel
+ background_opaque="true"
+ background_visible="true"
+ bg_alpha_color="DkGray"
+ bg_opaque_color="DkGray"
+ follows="all"
+ height="383"
+ label="BLOCKED"
+ layout="topleft"
+ left="0"
+ help_topic="people_blocked_tab"
+ name="blocked_panel"
+ right="-1"
+ top="0">
+ <panel
+ class="panel_block_list_sidetray"
+ height="383"
+ name="panel_block_list_sidetray"
+ filename="panel_block_list_sidetray.xml"
+ follows="all"
+ label="Blocked Residents &amp; Objects"
+ left="0"
+ font="SansSerifBold"
+ top="0"
+ right="-1" />
+ </panel>
+ </tab_container>
</panel>