LLUICtrl Params
Also adds support for requests_front boolean attribute to lluictrl from upstream
This commit is contained in:
@@ -31,7 +31,6 @@
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
//#include "llviewerprecompiledheaders.h"
|
||||
#include "linden_common.h"
|
||||
#include "lluictrl.h"
|
||||
#include "llfocusmgr.h"
|
||||
@@ -39,10 +38,67 @@
|
||||
|
||||
static LLRegisterWidget<LLUICtrl> r("ui_ctrl");
|
||||
|
||||
// NOTE: the LLFocusableElement implementation has been moved to llfocusmgr.cpp, to mirror the header where the class is defined.
|
||||
LLUICtrl::CallbackParam::CallbackParam()
|
||||
: name("name"),
|
||||
function_name("function"),
|
||||
parameter("parameter"),
|
||||
control_name("control") // Shortcut to control -> "control_name" for backwards compatability
|
||||
{
|
||||
addSynonym(parameter, "userdata");
|
||||
}
|
||||
|
||||
LLUICtrl::LLUICtrl() :
|
||||
mViewModel(LLViewModelPtr(new LLViewModel)),
|
||||
LLUICtrl::EnableControls::EnableControls()
|
||||
: enabled("enabled_control"),
|
||||
disabled("disabled_control")
|
||||
{}
|
||||
|
||||
LLUICtrl::ControlVisibility::ControlVisibility()
|
||||
: visible("visibility_control"),
|
||||
invisible("invisibility_control")
|
||||
{
|
||||
addSynonym(visible, "visiblity_control");
|
||||
addSynonym(invisible, "invisiblity_control");
|
||||
}
|
||||
|
||||
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"),
|
||||
commit_callback("commit_callback"),
|
||||
validate_callback("validate_callback"),
|
||||
mouseenter_callback("mouseenter_callback"),
|
||||
mouseleave_callback("mouseleave_callback"),
|
||||
control_name("control_name"),
|
||||
font("font", LLFontGL::getFontSansSerif()),
|
||||
font_halign("halign"),
|
||||
font_valign("valign"),
|
||||
length("length"), // ignore LLXMLNode cruft
|
||||
type("type") // ignore LLXMLNode cruft
|
||||
{
|
||||
addSynonym(initial_value, "initial_value");
|
||||
}
|
||||
|
||||
// NOTE: the LLFocusableElement implementation has been moved from here to llfocusmgr.cpp.
|
||||
|
||||
//static
|
||||
const LLUICtrl::Params& LLUICtrl::getDefaultParams()
|
||||
{
|
||||
// Singu Note: We diverge here, not using LLUICtrlFactory::getDefaultParams
|
||||
static const Params p;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel)
|
||||
: LLView(p),
|
||||
mIsChrome(FALSE),
|
||||
mRequestsFront(p.requests_front),
|
||||
mTabStop(TRUE),
|
||||
mTentative(FALSE),
|
||||
mViewModel(viewmodel),
|
||||
mEnabledControlVariable(NULL),
|
||||
mDisabledControlVariable(NULL),
|
||||
mMakeVisibleControlVariable(NULL),
|
||||
@@ -56,26 +112,110 @@ LLUICtrl::LLUICtrl() :
|
||||
mRightMouseDownSignal(NULL),
|
||||
mRightMouseUpSignal(NULL),
|
||||
mDoubleClickSignal(NULL),
|
||||
mTentative(FALSE),
|
||||
mTabStop(TRUE),
|
||||
mIsChrome(FALSE),
|
||||
mCommitOnReturn(FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
void LLUICtrl::initFromParams(const Params& p)
|
||||
{
|
||||
LLView::initFromParams(p);
|
||||
|
||||
mRequestsFront = p.requests_front;
|
||||
|
||||
setIsChrome(p.chrome);
|
||||
if(p.enabled_controls.isProvided())
|
||||
{
|
||||
if (p.enabled_controls.enabled.isChosen())
|
||||
{
|
||||
LLControlVariable* control = findControl(p.enabled_controls.enabled);
|
||||
if (control)
|
||||
setEnabledControlVariable(control);
|
||||
}
|
||||
else if(p.enabled_controls.disabled.isChosen())
|
||||
{
|
||||
LLControlVariable* control = findControl(p.enabled_controls.disabled);
|
||||
if (control)
|
||||
setDisabledControlVariable(control);
|
||||
}
|
||||
}
|
||||
if(p.controls_visibility.isProvided())
|
||||
{
|
||||
if (p.controls_visibility.visible.isChosen())
|
||||
{
|
||||
LLControlVariable* control = findControl(p.controls_visibility.visible);
|
||||
if (control)
|
||||
setMakeVisibleControlVariable(control);
|
||||
}
|
||||
else if (p.controls_visibility.invisible.isChosen())
|
||||
{
|
||||
LLControlVariable* control = findControl(p.controls_visibility.invisible);
|
||||
if (control)
|
||||
setMakeInvisibleControlVariable(control);
|
||||
}
|
||||
}
|
||||
|
||||
setTabStop(p.tab_stop);
|
||||
|
||||
if (p.initial_value.isProvided()
|
||||
&& !p.control_name.isProvided())
|
||||
{
|
||||
setValue(p.initial_value);
|
||||
}
|
||||
|
||||
if (p.commit_callback.isProvided())
|
||||
{
|
||||
setCommitCallback(initCommitCallback(p.commit_callback));
|
||||
}
|
||||
|
||||
if (p.validate_callback.isProvided())
|
||||
{
|
||||
setValidateCallback(initEnableCallback(p.validate_callback));
|
||||
}
|
||||
|
||||
if (p.init_callback.isProvided())
|
||||
{
|
||||
if (p.init_callback.function.isProvided())
|
||||
{
|
||||
p.init_callback.function()(this, p.init_callback.parameter);
|
||||
}
|
||||
else
|
||||
{
|
||||
commit_callback_t* initfunc = (CommitCallbackRegistry::getValue(p.init_callback.function_name));
|
||||
if (initfunc)
|
||||
{
|
||||
(*initfunc)(this, p.init_callback.parameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(p.mouseenter_callback.isProvided())
|
||||
{
|
||||
setMouseEnterCallback(initCommitCallback(p.mouseenter_callback));
|
||||
}
|
||||
|
||||
if(p.mouseleave_callback.isProvided())
|
||||
{
|
||||
setMouseLeaveCallback(initCommitCallback(p.mouseleave_callback));
|
||||
}
|
||||
}
|
||||
|
||||
LLUICtrl::LLUICtrl(const std::string& name, const LLRect rect, BOOL mouse_opaque,
|
||||
commit_callback_t commit_callback,
|
||||
U32 reshape)
|
||||
: // can't make this automatically follow top and left, breaks lots
|
||||
// of buttons in the UI. JC 7/20/2002
|
||||
LLView( name, rect, mouse_opaque, reshape ),
|
||||
mIsChrome(FALSE),
|
||||
mRequestsFront(false),
|
||||
mTabStop( TRUE ),
|
||||
mTentative( FALSE ),
|
||||
mViewModel(LLViewModelPtr(new LLViewModel)),
|
||||
mEnabledControlVariable(NULL),
|
||||
mDisabledControlVariable(NULL),
|
||||
mMakeVisibleControlVariable(NULL),
|
||||
mMakeInvisibleControlVariable(NULL),
|
||||
mCommitSignal(NULL),
|
||||
mValidateSignal(NULL),
|
||||
mViewModel(LLViewModelPtr(new LLViewModel)),
|
||||
mMouseEnterSignal(NULL),
|
||||
mMouseLeaveSignal(NULL),
|
||||
mMouseDownSignal(NULL),
|
||||
@@ -83,9 +223,6 @@ LLUICtrl::LLUICtrl(const std::string& name, const LLRect rect, BOOL mouse_opaque
|
||||
mRightMouseDownSignal(NULL),
|
||||
mRightMouseUpSignal(NULL),
|
||||
mDoubleClickSignal(NULL),
|
||||
mTentative( FALSE ),
|
||||
mTabStop( TRUE ),
|
||||
mIsChrome(FALSE),
|
||||
mCommitOnReturn(FALSE)
|
||||
{
|
||||
if(commit_callback)
|
||||
@@ -113,6 +250,66 @@ LLUICtrl::~LLUICtrl()
|
||||
delete mDoubleClickSignal;
|
||||
}
|
||||
|
||||
void default_commit_handler(LLUICtrl* ctrl, const LLSD& param)
|
||||
{}
|
||||
|
||||
bool default_enable_handler(LLUICtrl* ctrl, const LLSD& param)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
LLUICtrl::commit_signal_t::slot_type LLUICtrl::initCommitCallback(const CommitCallbackParam& cb)
|
||||
{
|
||||
if (cb.function.isProvided())
|
||||
{
|
||||
if (cb.parameter.isProvided())
|
||||
return boost::bind(cb.function(), _1, cb.parameter);
|
||||
else
|
||||
return cb.function();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string function_name = cb.function_name;
|
||||
commit_callback_t* func = (CommitCallbackRegistry::getValue(function_name));
|
||||
if (func)
|
||||
{
|
||||
if (cb.parameter.isProvided())
|
||||
return boost::bind((*func), _1, cb.parameter);
|
||||
else
|
||||
return commit_signal_t::slot_type(*func);
|
||||
}
|
||||
else if (!function_name.empty())
|
||||
{
|
||||
llwarns << "No callback found for: '" << function_name << "' in control: " << getName() << llendl;
|
||||
}
|
||||
}
|
||||
return default_commit_handler;
|
||||
}
|
||||
|
||||
LLUICtrl::enable_signal_t::slot_type LLUICtrl::initEnableCallback(const EnableCallbackParam& cb)
|
||||
{
|
||||
// Set the callback function
|
||||
if (cb.function.isProvided())
|
||||
{
|
||||
if (cb.parameter.isProvided())
|
||||
return boost::bind(cb.function(), this, cb.parameter);
|
||||
else
|
||||
return cb.function();
|
||||
}
|
||||
else
|
||||
{
|
||||
enable_callback_t* func = (EnableCallbackRegistry::getValue(cb.function_name));
|
||||
if (func)
|
||||
{
|
||||
if (cb.parameter.isProvided())
|
||||
return boost::bind((*func), this, cb.parameter);
|
||||
else
|
||||
return enable_signal_t::slot_type(*func);
|
||||
}
|
||||
}
|
||||
return default_enable_handler;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLUICtrl::onMouseEnter(S32 x, S32 y, MASK mask)
|
||||
@@ -136,6 +333,7 @@ void LLUICtrl::onMouseLeave(S32 x, S32 y, MASK mask)
|
||||
BOOL LLUICtrl::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
BOOL handled = LLView::handleMouseDown(x,y,mask);
|
||||
|
||||
if (mMouseDownSignal)
|
||||
{
|
||||
(*mMouseDownSignal)(this,x,y,mask);
|
||||
@@ -233,6 +431,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();
|
||||
}
|
||||
|
||||
void LLUICtrl::setEnabledControlVariable(LLControlVariable* control)
|
||||
{
|
||||
if (mEnabledControlVariable)
|
||||
@@ -429,7 +657,6 @@ void LLUICtrl::setIsChrome(BOOL is_chrome)
|
||||
// virtual
|
||||
BOOL LLUICtrl::getIsChrome() const
|
||||
{
|
||||
|
||||
LLView* parent_ctrl = getParent();
|
||||
while(parent_ctrl)
|
||||
{
|
||||
@@ -579,6 +806,7 @@ BOOL LLUICtrl::focusLastItem(BOOL prefer_text_fields)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BOOL LLUICtrl::focusNextItem(BOOL text_fields_only)
|
||||
{
|
||||
// this assumes that this method is called on the focus root.
|
||||
@@ -664,6 +892,8 @@ void LLUICtrl::initFromXML(LLXMLNodePtr node, LLView* parent)
|
||||
|
||||
setTabStop(has_tab_stop);
|
||||
|
||||
node->getAttributeBOOL("requests_front", mRequestsFront);
|
||||
|
||||
std::string str = node->getName()->mString;
|
||||
std::string attrib_str;
|
||||
LLXMLNodePtr child_node;
|
||||
@@ -787,6 +1017,7 @@ boost::signals2::connection LLUICtrl::setValidateBeforeCommit( boost::function<b
|
||||
if (!mValidateSignal) mValidateSignal = new enable_signal_t();
|
||||
return mValidateSignal->connect(boost::bind(cb, _2));
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLUICtrl::setTentative(BOOL b)
|
||||
{
|
||||
@@ -816,6 +1047,16 @@ void LLUICtrl::setMinValue(LLSD min_value)
|
||||
void LLUICtrl::setMaxValue(LLSD max_value)
|
||||
{ }
|
||||
|
||||
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();
|
||||
|
||||
@@ -34,13 +34,13 @@
|
||||
#ifndef LL_LLUICTRL_H
|
||||
#define LL_LLUICTRL_H
|
||||
|
||||
#include "llview.h"
|
||||
#include "llrect.h"
|
||||
#include "llsd.h"
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/signals2.hpp>
|
||||
|
||||
#include "llinitparam.h"
|
||||
#include "llview.h"
|
||||
#include "llviewmodel.h" // *TODO move dependency to .cpp file
|
||||
|
||||
class LLUICtrl
|
||||
@@ -49,20 +49,102 @@ class LLUICtrl
|
||||
public:
|
||||
typedef boost::function<void (LLUICtrl* ctrl, const LLSD& param)> commit_callback_t;
|
||||
typedef boost::signals2::signal<void (LLUICtrl* ctrl, const LLSD& param)> commit_signal_t;
|
||||
// *TODO: add xml support for this type of signal in the future
|
||||
typedef boost::signals2::signal<void (LLUICtrl* ctrl, S32 x, S32 y, MASK mask)> mouse_signal_t;
|
||||
|
||||
typedef boost::function<bool (LLUICtrl* ctrl, const LLSD& param)> enable_callback_t;
|
||||
typedef boost::signals2::signal<bool (LLUICtrl* ctrl, const LLSD& param), boost_boolean_combiner> enable_signal_t;
|
||||
|
||||
LLUICtrl();
|
||||
struct CallbackParam : public LLInitParam::Block<CallbackParam>
|
||||
{
|
||||
Ignored name;
|
||||
|
||||
Optional<std::string> function_name;
|
||||
Optional<LLSD> parameter;
|
||||
|
||||
Optional<std::string> control_name;
|
||||
|
||||
CallbackParam();
|
||||
};
|
||||
|
||||
struct CommitCallbackParam : public LLInitParam::Block<CommitCallbackParam, CallbackParam >
|
||||
{
|
||||
Optional<commit_callback_t> function;
|
||||
};
|
||||
|
||||
// also used for visible callbacks
|
||||
struct EnableCallbackParam : public LLInitParam::Block<EnableCallbackParam, CallbackParam >
|
||||
{
|
||||
Optional<enable_callback_t> function;
|
||||
};
|
||||
|
||||
struct EnableControls : public LLInitParam::ChoiceBlock<EnableControls>
|
||||
{
|
||||
Alternative<std::string> enabled;
|
||||
Alternative<std::string> disabled;
|
||||
|
||||
EnableControls();
|
||||
};
|
||||
struct ControlVisibility : public LLInitParam::ChoiceBlock<ControlVisibility>
|
||||
{
|
||||
Alternative<std::string> visible;
|
||||
Alternative<std::string> invisible;
|
||||
|
||||
ControlVisibility();
|
||||
};
|
||||
struct Params : public LLInitParam::Block<Params, LLView::Params>
|
||||
{
|
||||
Optional<std::string> label;
|
||||
Optional<bool> tab_stop,
|
||||
chrome,
|
||||
requests_front;
|
||||
Optional<LLSD> initial_value;
|
||||
|
||||
Optional<CommitCallbackParam> init_callback,
|
||||
commit_callback;
|
||||
Optional<EnableCallbackParam> validate_callback;
|
||||
|
||||
Optional<CommitCallbackParam> mouseenter_callback,
|
||||
mouseleave_callback;
|
||||
|
||||
Optional<std::string> control_name;
|
||||
Optional<EnableControls> enabled_controls;
|
||||
Optional<ControlVisibility> controls_visibility;
|
||||
|
||||
// font params
|
||||
Optional<const LLFontGL*> font;
|
||||
Optional<LLFontGL::HAlign> font_halign;
|
||||
Optional<LLFontGL::VAlign> font_valign;
|
||||
|
||||
// cruft from LLXMLNode implementation
|
||||
Ignored type,
|
||||
length;
|
||||
|
||||
Params();
|
||||
};
|
||||
|
||||
/*virtual*/ ~LLUICtrl();
|
||||
|
||||
void initFromParams(const Params& p);
|
||||
static const Params& getDefaultParams();
|
||||
LLUICtrl(const Params& p = getDefaultParams(),
|
||||
const LLViewModelPtr& viewmodel=LLViewModelPtr(new LLViewModel));
|
||||
// Singu Note: This constructor is deprecated:
|
||||
LLUICtrl( const std::string& name, const LLRect rect = LLRect(), BOOL mouse_opaque = TRUE,
|
||||
commit_callback_t commit_callback = NULL,
|
||||
U32 reshape=FOLLOWS_NONE);
|
||||
/*virtual*/ ~LLUICtrl();
|
||||
|
||||
commit_signal_t::slot_type initCommitCallback(const CommitCallbackParam& cb);
|
||||
enable_signal_t::slot_type initEnableCallback(const EnableCallbackParam& cb);
|
||||
|
||||
// We need this virtual so we can override it with derived versions
|
||||
virtual LLViewModel* getViewModel() const;
|
||||
// We shouldn't ever need to set this directly
|
||||
//virtual void setViewModel(const LLViewModelPtr&);
|
||||
|
||||
virtual BOOL postBuild();
|
||||
|
||||
public:
|
||||
// LLView interface
|
||||
/*virtual*/ void initFromXML(LLXMLNodePtr node, LLView* parent);
|
||||
/*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const;
|
||||
@@ -116,6 +198,9 @@ public:
|
||||
|
||||
// Default to no-op:
|
||||
virtual void onTabInto();
|
||||
|
||||
// Clear any user-provided input (text in a text editor, checked checkbox,
|
||||
// selected radio button, etc.). Defaults to no-op.
|
||||
virtual void clear();
|
||||
virtual void setColor(const LLColor4& color);
|
||||
virtual void setAlpha(F32 alpha);
|
||||
@@ -124,7 +209,7 @@ public:
|
||||
|
||||
BOOL focusNextItem(BOOL text_entry_only);
|
||||
BOOL focusPrevItem(BOOL text_entry_only);
|
||||
virtual BOOL focusFirstItem(BOOL prefer_text_fields = FALSE, BOOL focus_flash = TRUE );
|
||||
BOOL focusFirstItem(BOOL prefer_text_fields = FALSE, BOOL focus_flash = TRUE );
|
||||
BOOL focusLastItem(BOOL prefer_text_fields = FALSE);
|
||||
|
||||
// Non Virtuals
|
||||
@@ -139,10 +224,13 @@ public:
|
||||
void setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; }
|
||||
BOOL getCommitOnReturn() const { return mCommitOnReturn; }
|
||||
|
||||
boost::signals2::connection setCommitCallback(const CommitCallbackParam& cb);
|
||||
boost::signals2::connection setValidateCallback(const EnableCallbackParam& cb);
|
||||
|
||||
//Start using these!
|
||||
boost::signals2::connection setCommitCallback( const commit_signal_t::slot_type& cb );
|
||||
boost::signals2::connection setValidateCallback( const enable_signal_t::slot_type& cb );
|
||||
|
||||
|
||||
boost::signals2::connection setMouseEnterCallback( const commit_signal_t::slot_type& cb );
|
||||
boost::signals2::connection setMouseLeaveCallback( const commit_signal_t::slot_type& cb );
|
||||
|
||||
@@ -205,8 +293,9 @@ protected:
|
||||
boost::signals2::connection mMakeInvisibleControlConnection;
|
||||
private:
|
||||
|
||||
BOOL mTabStop;
|
||||
BOOL mIsChrome;
|
||||
BOOL mRequestsFront;
|
||||
BOOL mTabStop;
|
||||
BOOL mTentative;
|
||||
|
||||
bool mCommitOnReturn;
|
||||
|
||||
Reference in New Issue
Block a user