summaryrefslogtreecommitdiff
path: root/indra/llui/lluictrl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui/lluictrl.cpp')
-rwxr-xr-x[-rw-r--r--]indra/llui/lluictrl.cpp336
1 files changed, 222 insertions, 114 deletions
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index 3ade46d367..df74e113e9 100644..100755
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -3,31 +3,25 @@
* @author James Cook, Richard Nelson, Tom Yedwab
* @brief Abstract base class for UI controls
*
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 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.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * 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.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * 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$
*/
@@ -35,13 +29,18 @@
#define LLUICTRL_CPP
#include "lluictrl.h"
-
+#include "llviewereventrecorder.h"
#include "llfocusmgr.h"
#include "llpanel.h"
#include "lluictrlfactory.h"
+#include "lltabcontainer.h"
+#include "llaccordionctrltab.h"
static LLDefaultChildRegistry::Register<LLUICtrl> r("ui_ctrl");
+F32 LLUICtrl::sActiveControlTransparency = 1.0f;
+F32 LLUICtrl::sInactiveControlTransparency = 1.0f;
+
// Compiler optimization, generate extern template
template class LLUICtrl* LLView::getChild<class LLUICtrl>(
const std::string& name, BOOL recurse) const;
@@ -71,6 +70,7 @@ LLUICtrl::ControlVisibility::ControlVisibility()
LLUICtrl::Params::Params()
: tab_stop("tab_stop", true),
chrome("chrome", false),
+ requests_front("requests_front", false),
label("label"),
initial_value("value"),
init_callback("init_callback"),
@@ -99,8 +99,10 @@ const LLUICtrl::Params& LLUICtrl::getDefaultParams()
LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel)
: LLView(p),
- mTentative(FALSE),
mIsChrome(FALSE),
+ mRequestsFront(p.requests_front),
+ mTabStop(FALSE),
+ mTentative(FALSE),
mViewModel(viewmodel),
mControlVariable(NULL),
mEnabledControlVariable(NULL),
@@ -115,15 +117,18 @@ LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel)
mMouseUpSignal(NULL),
mRightMouseDownSignal(NULL),
mRightMouseUpSignal(NULL),
- mDoubleClickSignal(NULL)
+ mDoubleClickSignal(NULL),
+ mTransparencyType(TT_DEFAULT)
{
- mUICtrlHandle.bind(this);
+ claimMem(viewmodel.get());
}
void LLUICtrl::initFromParams(const Params& p)
{
LLView::initFromParams(p);
+ mRequestsFront = p.requests_front;
+
setIsChrome(p.chrome);
setControlName(p.control_name);
if(p.enabled_controls.isProvided())
@@ -209,7 +214,7 @@ LLUICtrl::~LLUICtrl()
if( gFocusMgr.getTopCtrl() == this )
{
- llwarns << "UI Control holding top ctrl deleted: " << getName() << ". Top view removed." << llendl;
+ LL_WARNS() << "UI Control holding top ctrl deleted: " << getName() << ". Top view removed." << LL_ENDL;
gFocusMgr.removeTopCtrlWithoutCallback( this );
}
@@ -255,7 +260,7 @@ LLUICtrl::commit_signal_t::slot_type LLUICtrl::initCommitCallback(const CommitCa
}
else if (!function_name.empty())
{
- llwarns << "No callback found for: '" << function_name << "' in control: " << getName() << llendl;
+ LL_WARNS() << "No callback found for: '" << function_name << "' in control: " << getName() << LL_ENDL;
}
}
return default_commit_handler;
@@ -306,22 +311,40 @@ void LLUICtrl::onMouseLeave(S32 x, S32 y, MASK mask)
//virtual
BOOL LLUICtrl::handleMouseDown(S32 x, S32 y, MASK mask)
{
+
+ LL_DEBUGS() << "LLUICtrl::handleMouseDown calling LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << LL_ENDL;
+
BOOL handled = LLView::handleMouseDown(x,y,mask);
+
if (mMouseDownSignal)
{
(*mMouseDownSignal)(this,x,y,mask);
}
+ LL_DEBUGS() << "LLUICtrl::handleMousedown - handled is returning as: " << handled << " " << LL_ENDL;
+
+ if (handled) {
+ LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-56,-56,getPathname());
+ }
return handled;
}
//virtual
BOOL LLUICtrl::handleMouseUp(S32 x, S32 y, MASK mask)
{
+
+ LL_DEBUGS() << "LLUICtrl::handleMouseUp calling LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << LL_ENDL;
+
BOOL handled = LLView::handleMouseUp(x,y,mask);
+ if (handled) {
+ LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-56,-56,getPathname());
+ }
if (mMouseUpSignal)
{
(*mMouseUpSignal)(this,x,y,mask);
}
+
+ LL_DEBUGS() << "LLUICtrl::handleMouseUp - handled for xui " << getPathname() << " - is returning as: " << handled << " " << LL_ENDL;
+
return handled;
}
@@ -404,6 +427,36 @@ LLViewModel* LLUICtrl::getViewModel() const
return mViewModel;
}
+//virtual
+BOOL LLUICtrl::postBuild()
+{
+ //
+ // Find all of the children that want to be in front and move them to the front
+ //
+
+ if (getChildCount() > 0)
+ {
+ std::vector<LLUICtrl*> childrenToMoveToFront;
+
+ for (LLView::child_list_const_iter_t child_it = beginChild(); child_it != endChild(); ++child_it)
+ {
+ LLUICtrl* uictrl = dynamic_cast<LLUICtrl*>(*child_it);
+
+ if (uictrl && uictrl->mRequestsFront)
+ {
+ childrenToMoveToFront.push_back(uictrl);
+ }
+ }
+
+ for (std::vector<LLUICtrl*>::iterator it = childrenToMoveToFront.begin(); it != childrenToMoveToFront.end(); ++it)
+ {
+ sendChildToFront(*it);
+ }
+ }
+
+ return LLView::postBuild();
+}
+
bool LLUICtrl::setControlValue(const LLSD& value)
{
if (mControlVariable)
@@ -419,7 +472,7 @@ void LLUICtrl::setControlVariable(LLControlVariable* control)
if (mControlVariable)
{
//RN: this will happen in practice, should we try to avoid it?
- //llwarns << "setControlName called twice on same control!" << llendl;
+ //LL_WARNS() << "setControlName called twice on same control!" << LL_ENDL;
mControlConnection.disconnect(); // disconnect current signal
mControlVariable = NULL;
}
@@ -427,7 +480,7 @@ void LLUICtrl::setControlVariable(LLControlVariable* control)
if (control)
{
mControlVariable = control;
- mControlConnection = mControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getUICtrlHandle(), std::string("value")));
+ mControlConnection = mControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getHandle(), std::string("value")));
setValue(mControlVariable->getValue());
}
}
@@ -458,7 +511,7 @@ void LLUICtrl::setEnabledControlVariable(LLControlVariable* control)
if (control)
{
mEnabledControlVariable = control;
- mEnabledControlConnection = mEnabledControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getUICtrlHandle(), std::string("enabled")));
+ mEnabledControlConnection = mEnabledControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getHandle(), std::string("enabled")));
setEnabled(mEnabledControlVariable->getValue().asBoolean());
}
}
@@ -473,7 +526,7 @@ void LLUICtrl::setDisabledControlVariable(LLControlVariable* control)
if (control)
{
mDisabledControlVariable = control;
- mDisabledControlConnection = mDisabledControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getUICtrlHandle(), std::string("disabled")));
+ mDisabledControlConnection = mDisabledControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getHandle(), std::string("disabled")));
setEnabled(!(mDisabledControlVariable->getValue().asBoolean()));
}
}
@@ -488,7 +541,7 @@ void LLUICtrl::setMakeVisibleControlVariable(LLControlVariable* control)
if (control)
{
mMakeVisibleControlVariable = control;
- mMakeVisibleControlConnection = mMakeVisibleControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getUICtrlHandle(), std::string("visible")));
+ mMakeVisibleControlConnection = mMakeVisibleControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getHandle(), std::string("visible")));
setVisible(mMakeVisibleControlVariable->getValue().asBoolean());
}
}
@@ -503,7 +556,7 @@ void LLUICtrl::setMakeInvisibleControlVariable(LLControlVariable* control)
if (control)
{
mMakeInvisibleControlVariable = control;
- mMakeInvisibleControlConnection = mMakeInvisibleControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getUICtrlHandle(), std::string("invisible")));
+ mMakeInvisibleControlConnection = mMakeInvisibleControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getHandle(), std::string("invisible")));
setVisible(!(mMakeInvisibleControlVariable->getValue().asBoolean()));
}
}
@@ -669,51 +722,19 @@ BOOL LLUICtrl::getIsChrome() const
}
}
-// this comparator uses the crazy disambiguating logic of LLCompareByTabOrder,
-// but to switch up the order so that children that have the default tab group come first
-// and those that are prior to the default tab group come last
-class CompareByDefaultTabGroup: public LLCompareByTabOrder
-{
-public:
- CompareByDefaultTabGroup(LLView::child_tab_order_t order, S32 default_tab_group):
- LLCompareByTabOrder(order),
- mDefaultTabGroup(default_tab_group) {}
-private:
- /*virtual*/ bool compareTabOrders(const LLView::tab_order_t & a, const LLView::tab_order_t & b) const
- {
- S32 ag = a.first; // tab group for a
- S32 bg = b.first; // tab group for b
- // these two ifs have the effect of moving elements prior to the default tab group to the end of the list
- // (still sorted relative to each other, though)
- if(ag < mDefaultTabGroup && bg >= mDefaultTabGroup) return false;
- if(bg < mDefaultTabGroup && ag >= mDefaultTabGroup) return true;
- return a < b; // sort correctly if they're both on the same side of the default tab group
- }
- S32 mDefaultTabGroup;
-};
-// Sorter for plugging into the query.
-// I'd have defined it local to the one method that uses it but that broke the VS 05 compiler. -MG
-class LLUICtrl::DefaultTabGroupFirstSorter : public LLQuerySorter, public LLSingleton<DefaultTabGroupFirstSorter>
-{
-public:
- /*virtual*/ void operator() (LLView * parent, viewList_t &children) const
- {
- children.sort(CompareByDefaultTabGroup(parent->getCtrlOrder(), parent->getDefaultTabGroup()));
- }
-};
+LLTrace::BlockTimerStatHandle FTM_FOCUS_FIRST_ITEM("Focus First Item");
BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields, BOOL focus_flash)
{
+ LL_RECORD_BLOCK_TIME(FTM_FOCUS_FIRST_ITEM);
// try to select default tab group child
- LLCtrlQuery query = getTabOrderQuery();
- // sort things such that the default tab group is at the front
- query.setSorter(DefaultTabGroupFirstSorter::getInstance());
+ LLViewQuery query = getTabOrderQuery();
child_list_t result = query(this);
if(result.size() > 0)
{
- LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.front());
+ LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.back());
if(!ctrl->hasFocus())
{
ctrl->setFocus(TRUE);
@@ -728,17 +749,20 @@ BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields, BOOL focus_flash)
// search for text field first
if(prefer_text_fields)
{
- LLCtrlQuery query = getTabOrderQuery();
+ LLViewQuery query = getTabOrderQuery();
query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance());
child_list_t result = query(this);
if(result.size() > 0)
{
- LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.front());
+ LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.back());
if(!ctrl->hasFocus())
{
ctrl->setFocus(TRUE);
ctrl->onTabInto();
- gFocusMgr.triggerFocusFlash();
+ if(focus_flash)
+ {
+ gFocusMgr.triggerFocusFlash();
+ }
}
return TRUE;
}
@@ -747,58 +771,26 @@ BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields, BOOL focus_flash)
result = getTabOrderQuery().run(this);
if(result.size() > 0)
{
- LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.front());
+ LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.back());
if(!ctrl->hasFocus())
{
ctrl->setFocus(TRUE);
ctrl->onTabInto();
- gFocusMgr.triggerFocusFlash();
- }
- return TRUE;
- }
- return FALSE;
-}
-
-BOOL LLUICtrl::focusLastItem(BOOL prefer_text_fields)
-{
- // search for text field first
- if(prefer_text_fields)
- {
- LLCtrlQuery query = getTabOrderQuery();
- query.addPreFilter(LLUICtrl::LLTextInputFilter::getInstance());
- child_list_t result = query(this);
- if(result.size() > 0)
- {
- LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.back());
- if(!ctrl->hasFocus())
+ if(focus_flash)
{
- ctrl->setFocus(TRUE);
- ctrl->onTabInto();
gFocusMgr.triggerFocusFlash();
}
- return TRUE;
- }
- }
- // no text field found, or we don't care about text fields
- child_list_t result = getTabOrderQuery().run(this);
- if(result.size() > 0)
- {
- LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.back());
- if(!ctrl->hasFocus())
- {
- ctrl->setFocus(TRUE);
- ctrl->onTabInto();
- gFocusMgr.triggerFocusFlash();
}
return TRUE;
}
return FALSE;
}
+
BOOL LLUICtrl::focusNextItem(BOOL text_fields_only)
{
// this assumes that this method is called on the focus root.
- LLCtrlQuery query = getTabOrderQuery();
+ LLViewQuery query = getTabOrderQuery();
static LLUICachedControl<bool> tab_to_text_fields_only ("TabToTextFieldsOnly", false);
if(text_fields_only || tab_to_text_fields_only)
{
@@ -811,7 +803,7 @@ BOOL LLUICtrl::focusNextItem(BOOL text_fields_only)
BOOL LLUICtrl::focusPrevItem(BOOL text_fields_only)
{
// this assumes that this method is called on the focus root.
- LLCtrlQuery query = getTabOrderQuery();
+ LLViewQuery query = getTabOrderQuery();
static LLUICachedControl<bool> tab_to_text_fields_only ("TabToTextFieldsOnly", false);
if(text_fields_only || tab_to_text_fields_only)
{
@@ -825,7 +817,7 @@ LLUICtrl* LLUICtrl::findRootMostFocusRoot()
{
LLUICtrl* focus_root = NULL;
LLUICtrl* next_view = this;
- while(next_view)
+ while(next_view && next_view->hasTabStop())
{
if (next_view->isFocusRoot())
{
@@ -868,8 +860,26 @@ bool LLUICtrl::findHelpTopic(std::string& help_topic_out)
if (panel)
{
+
+ LLView *child;
+ LLPanel *subpanel = NULL;
+
// does the panel have a sub-panel with a help topic?
- LLPanel *subpanel = panel->childGetVisiblePanelWithHelp();
+ bfs_tree_iterator_t it = beginTreeBFS();
+ // skip ourselves
+ ++it;
+ for (; it != endTreeBFS(); ++it)
+ {
+ child = *it;
+ // do we have a panel with a help topic?
+ LLPanel *panel = dynamic_cast<LLPanel *>(child);
+ if (panel && panel->isInVisibleChain() && !panel->getHelpTopic().empty())
+ {
+ subpanel = panel;
+ break;
+ }
+ }
+
if (subpanel)
{
help_topic_out = subpanel->getHelpTopic();
@@ -877,10 +887,41 @@ bool LLUICtrl::findHelpTopic(std::string& help_topic_out)
}
// does the panel have an active tab with a help topic?
- LLPanel *tab = panel->childGetVisibleTabWithHelp();
- if (tab)
+ LLPanel *tab_panel = NULL;
+
+ it = beginTreeBFS();
+ // skip ourselves
+ ++it;
+ for (; it != endTreeBFS(); ++it)
+ {
+ child = *it;
+ LLPanel *curTabPanel = NULL;
+
+ // do we have a tab container?
+ LLTabContainer *tab = dynamic_cast<LLTabContainer *>(child);
+ if (tab && tab->getVisible())
+ {
+ curTabPanel = tab->getCurrentPanel();
+ }
+
+ // do we have an accordion tab?
+ LLAccordionCtrlTab* accordion = dynamic_cast<LLAccordionCtrlTab *>(child);
+ if (accordion && accordion->getDisplayChildren())
+ {
+ curTabPanel = dynamic_cast<LLPanel *>(accordion->getAccordionView());
+ }
+
+ // if we found a valid tab, does it have a help topic?
+ if (curTabPanel && !curTabPanel->getHelpTopic().empty())
+ {
+ tab_panel = curTabPanel;
+ break;
+ }
+ }
+
+ if (tab_panel)
{
- help_topic_out = tab->getHelpTopic();
+ help_topic_out = tab_panel->getHelpTopic();
return true; // success (tab)
}
@@ -906,6 +947,8 @@ boost::signals2::connection LLUICtrl::setCommitCallback( boost::function<void (L
boost::signals2::connection LLUICtrl::setValidateBeforeCommit( boost::function<bool (const LLSD& data)> cb )
{
if (!mValidateSignal) mValidateSignal = new enable_signal_t();
+ claimMem(mValidateSignal);
+
return mValidateSignal->connect(boost::bind(cb, _2));
}
@@ -925,56 +968,121 @@ BOOL LLUICtrl::getTentative() const
void LLUICtrl::setColor(const LLColor4& color)
{ }
+F32 LLUICtrl::getCurrentTransparency()
+{
+ F32 alpha = 0;
+
+ switch(mTransparencyType)
+ {
+ case TT_DEFAULT:
+ alpha = getDrawContext().mAlpha;
+ break;
+
+ case TT_ACTIVE:
+ alpha = sActiveControlTransparency;
+ break;
+
+ case TT_INACTIVE:
+ alpha = sInactiveControlTransparency;
+ break;
+
+ case TT_FADING:
+ alpha = sInactiveControlTransparency / 2;
+ break;
+ }
+
+ return alpha;
+}
+
+void LLUICtrl::setTransparencyType(ETypeTransparency type)
+{
+ mTransparencyType = type;
+}
+
+boost::signals2::connection LLUICtrl::setCommitCallback(const CommitCallbackParam& cb)
+{
+ return setCommitCallback(initCommitCallback(cb));
+}
+
+boost::signals2::connection LLUICtrl::setValidateCallback(const EnableCallbackParam& cb)
+{
+ return setValidateCallback(initEnableCallback(cb));
+}
+
boost::signals2::connection LLUICtrl::setCommitCallback( const commit_signal_t::slot_type& cb )
{
if (!mCommitSignal) mCommitSignal = new commit_signal_t();
+ claimMem(mCommitSignal);
+
return mCommitSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setValidateCallback( const enable_signal_t::slot_type& cb )
{
if (!mValidateSignal) mValidateSignal = new enable_signal_t();
+ claimMem(mValidateSignal);
+
return mValidateSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setMouseEnterCallback( const commit_signal_t::slot_type& cb )
{
if (!mMouseEnterSignal) mMouseEnterSignal = new commit_signal_t();
+ claimMem(mMouseEnterSignal);
+
return mMouseEnterSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setMouseLeaveCallback( const commit_signal_t::slot_type& cb )
{
if (!mMouseLeaveSignal) mMouseLeaveSignal = new commit_signal_t();
+ claimMem(mMouseLeaveSignal);
+
return mMouseLeaveSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setMouseDownCallback( const mouse_signal_t::slot_type& cb )
{
if (!mMouseDownSignal) mMouseDownSignal = new mouse_signal_t();
+ claimMem(mMouseDownSignal);
+
return mMouseDownSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setMouseUpCallback( const mouse_signal_t::slot_type& cb )
{
if (!mMouseUpSignal) mMouseUpSignal = new mouse_signal_t();
+ claimMem(mMouseUpSignal);
+
return mMouseUpSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setRightMouseDownCallback( const mouse_signal_t::slot_type& cb )
{
if (!mRightMouseDownSignal) mRightMouseDownSignal = new mouse_signal_t();
+ claimMem(mRightMouseDownSignal);
+
return mRightMouseDownSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setRightMouseUpCallback( const mouse_signal_t::slot_type& cb )
{
if (!mRightMouseUpSignal) mRightMouseUpSignal = new mouse_signal_t();
+ claimMem(mRightMouseUpSignal);
+
return mRightMouseUpSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setDoubleClickCallback( const mouse_signal_t::slot_type& cb )
{
if (!mDoubleClickSignal) mDoubleClickSignal = new mouse_signal_t();
+ claimMem(mDoubleClickSignal);
+
return mDoubleClickSignal->connect(cb);
}
+
+void LLUICtrl::addInfo(LLSD & info)
+{
+ LLView::addInfo(info);
+ info["value"] = getValue();
+}