LLUICtrl Params

Also adds support for requests_front boolean attribute to lluictrl from upstream
This commit is contained in:
Inusaito Sayori
2013-12-02 20:17:48 -05:00
parent 23958965aa
commit 4116ac75f6
2 changed files with 348 additions and 18 deletions

View File

@@ -31,7 +31,6 @@
* $/LicenseInfo$ * $/LicenseInfo$
*/ */
//#include "llviewerprecompiledheaders.h"
#include "linden_common.h" #include "linden_common.h"
#include "lluictrl.h" #include "lluictrl.h"
#include "llfocusmgr.h" #include "llfocusmgr.h"
@@ -39,10 +38,67 @@
static LLRegisterWidget<LLUICtrl> r("ui_ctrl"); 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() : LLUICtrl::EnableControls::EnableControls()
mViewModel(LLViewModelPtr(new LLViewModel)), : 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), mEnabledControlVariable(NULL),
mDisabledControlVariable(NULL), mDisabledControlVariable(NULL),
mMakeVisibleControlVariable(NULL), mMakeVisibleControlVariable(NULL),
@@ -56,26 +112,110 @@ LLUICtrl::LLUICtrl() :
mRightMouseDownSignal(NULL), mRightMouseDownSignal(NULL),
mRightMouseUpSignal(NULL), mRightMouseUpSignal(NULL),
mDoubleClickSignal(NULL), mDoubleClickSignal(NULL),
mTentative(FALSE),
mTabStop(TRUE),
mIsChrome(FALSE),
mCommitOnReturn(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, LLUICtrl::LLUICtrl(const std::string& name, const LLRect rect, BOOL mouse_opaque,
commit_callback_t commit_callback, commit_callback_t commit_callback,
U32 reshape) U32 reshape)
: // can't make this automatically follow top and left, breaks lots : // can't make this automatically follow top and left, breaks lots
// of buttons in the UI. JC 7/20/2002 // of buttons in the UI. JC 7/20/2002
LLView( name, rect, mouse_opaque, reshape ), LLView( name, rect, mouse_opaque, reshape ),
mIsChrome(FALSE),
mRequestsFront(false),
mTabStop( TRUE ),
mTentative( FALSE ),
mViewModel(LLViewModelPtr(new LLViewModel)),
mEnabledControlVariable(NULL), mEnabledControlVariable(NULL),
mDisabledControlVariable(NULL), mDisabledControlVariable(NULL),
mMakeVisibleControlVariable(NULL), mMakeVisibleControlVariable(NULL),
mMakeInvisibleControlVariable(NULL), mMakeInvisibleControlVariable(NULL),
mCommitSignal(NULL), mCommitSignal(NULL),
mValidateSignal(NULL), mValidateSignal(NULL),
mViewModel(LLViewModelPtr(new LLViewModel)),
mMouseEnterSignal(NULL), mMouseEnterSignal(NULL),
mMouseLeaveSignal(NULL), mMouseLeaveSignal(NULL),
mMouseDownSignal(NULL), mMouseDownSignal(NULL),
@@ -83,9 +223,6 @@ LLUICtrl::LLUICtrl(const std::string& name, const LLRect rect, BOOL mouse_opaque
mRightMouseDownSignal(NULL), mRightMouseDownSignal(NULL),
mRightMouseUpSignal(NULL), mRightMouseUpSignal(NULL),
mDoubleClickSignal(NULL), mDoubleClickSignal(NULL),
mTentative( FALSE ),
mTabStop( TRUE ),
mIsChrome(FALSE),
mCommitOnReturn(FALSE) mCommitOnReturn(FALSE)
{ {
if(commit_callback) if(commit_callback)
@@ -113,6 +250,66 @@ LLUICtrl::~LLUICtrl()
delete mDoubleClickSignal; 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 // virtual
void LLUICtrl::onMouseEnter(S32 x, S32 y, MASK mask) 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 LLUICtrl::handleMouseDown(S32 x, S32 y, MASK mask)
{ {
BOOL handled = LLView::handleMouseDown(x,y,mask); BOOL handled = LLView::handleMouseDown(x,y,mask);
if (mMouseDownSignal) if (mMouseDownSignal)
{ {
(*mMouseDownSignal)(this,x,y,mask); (*mMouseDownSignal)(this,x,y,mask);
@@ -233,6 +431,36 @@ LLViewModel* LLUICtrl::getViewModel() const
return mViewModel; 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) void LLUICtrl::setEnabledControlVariable(LLControlVariable* control)
{ {
if (mEnabledControlVariable) if (mEnabledControlVariable)
@@ -429,7 +657,6 @@ void LLUICtrl::setIsChrome(BOOL is_chrome)
// virtual // virtual
BOOL LLUICtrl::getIsChrome() const BOOL LLUICtrl::getIsChrome() const
{ {
LLView* parent_ctrl = getParent(); LLView* parent_ctrl = getParent();
while(parent_ctrl) while(parent_ctrl)
{ {
@@ -579,6 +806,7 @@ BOOL LLUICtrl::focusLastItem(BOOL prefer_text_fields)
return FALSE; return FALSE;
} }
BOOL LLUICtrl::focusNextItem(BOOL text_fields_only) BOOL LLUICtrl::focusNextItem(BOOL text_fields_only)
{ {
// this assumes that this method is called on the focus root. // 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); setTabStop(has_tab_stop);
node->getAttributeBOOL("requests_front", mRequestsFront);
std::string str = node->getName()->mString; std::string str = node->getName()->mString;
std::string attrib_str; std::string attrib_str;
LLXMLNodePtr child_node; LLXMLNodePtr child_node;
@@ -787,6 +1017,7 @@ boost::signals2::connection LLUICtrl::setValidateBeforeCommit( boost::function<b
if (!mValidateSignal) mValidateSignal = new enable_signal_t(); if (!mValidateSignal) mValidateSignal = new enable_signal_t();
return mValidateSignal->connect(boost::bind(cb, _2)); return mValidateSignal->connect(boost::bind(cb, _2));
} }
// virtual // virtual
void LLUICtrl::setTentative(BOOL b) void LLUICtrl::setTentative(BOOL b)
{ {
@@ -816,6 +1047,16 @@ void LLUICtrl::setMinValue(LLSD min_value)
void LLUICtrl::setMaxValue(LLSD max_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 ) boost::signals2::connection LLUICtrl::setCommitCallback( const commit_signal_t::slot_type& cb )
{ {
if (!mCommitSignal) mCommitSignal = new commit_signal_t(); if (!mCommitSignal) mCommitSignal = new commit_signal_t();

View File

@@ -34,13 +34,13 @@
#ifndef LL_LLUICTRL_H #ifndef LL_LLUICTRL_H
#define LL_LLUICTRL_H #define LL_LLUICTRL_H
#include "llview.h"
#include "llrect.h" #include "llrect.h"
#include "llsd.h" #include "llsd.h"
#include <boost/function.hpp> #include <boost/function.hpp>
#include <boost/signals2.hpp> #include <boost/signals2.hpp>
#include "llinitparam.h" #include "llinitparam.h"
#include "llview.h"
#include "llviewmodel.h" // *TODO move dependency to .cpp file #include "llviewmodel.h" // *TODO move dependency to .cpp file
class LLUICtrl class LLUICtrl
@@ -49,20 +49,102 @@ class LLUICtrl
public: public:
typedef boost::function<void (LLUICtrl* ctrl, const LLSD& param)> commit_callback_t; 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; 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::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::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; 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, LLUICtrl( const std::string& name, const LLRect rect = LLRect(), BOOL mouse_opaque = TRUE,
commit_callback_t commit_callback = NULL, commit_callback_t commit_callback = NULL,
U32 reshape=FOLLOWS_NONE); 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 // We need this virtual so we can override it with derived versions
virtual LLViewModel* getViewModel() const; virtual LLViewModel* getViewModel() const;
// We shouldn't ever need to set this directly // We shouldn't ever need to set this directly
//virtual void setViewModel(const LLViewModelPtr&); //virtual void setViewModel(const LLViewModelPtr&);
virtual BOOL postBuild();
public:
// LLView interface // LLView interface
/*virtual*/ void initFromXML(LLXMLNodePtr node, LLView* parent); /*virtual*/ void initFromXML(LLXMLNodePtr node, LLView* parent);
/*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const; /*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const;
@@ -116,6 +198,9 @@ public:
// Default to no-op: // Default to no-op:
virtual void onTabInto(); 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 clear();
virtual void setColor(const LLColor4& color); virtual void setColor(const LLColor4& color);
virtual void setAlpha(F32 alpha); virtual void setAlpha(F32 alpha);
@@ -124,7 +209,7 @@ public:
BOOL focusNextItem(BOOL text_entry_only); BOOL focusNextItem(BOOL text_entry_only);
BOOL focusPrevItem(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); BOOL focusLastItem(BOOL prefer_text_fields = FALSE);
// Non Virtuals // Non Virtuals
@@ -139,10 +224,13 @@ public:
void setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; } void setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; }
BOOL getCommitOnReturn() const { return mCommitOnReturn; } BOOL getCommitOnReturn() const { return mCommitOnReturn; }
boost::signals2::connection setCommitCallback(const CommitCallbackParam& cb);
boost::signals2::connection setValidateCallback(const EnableCallbackParam& cb);
//Start using these! //Start using these!
boost::signals2::connection setCommitCallback( const commit_signal_t::slot_type& cb ); 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 setValidateCallback( const enable_signal_t::slot_type& cb );
boost::signals2::connection setMouseEnterCallback( const commit_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 ); boost::signals2::connection setMouseLeaveCallback( const commit_signal_t::slot_type& cb );
@@ -205,8 +293,9 @@ protected:
boost::signals2::connection mMakeInvisibleControlConnection; boost::signals2::connection mMakeInvisibleControlConnection;
private: private:
BOOL mTabStop;
BOOL mIsChrome; BOOL mIsChrome;
BOOL mRequestsFront;
BOOL mTabStop;
BOOL mTentative; BOOL mTentative;
bool mCommitOnReturn; bool mCommitOnReturn;