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$
*/
//#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();

View File

@@ -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;