/** * @file lluictrl.h * @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. * * 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 * * 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 * * 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. * * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ #ifndef LL_LLUICTRL_H #define LL_LLUICTRL_H #include "llboost.h" #include "llrect.h" #include "llsd.h" #include #include "llinitparam.h" #include "llview.h" #include "llviewmodel.h" const BOOL TAKE_FOCUS_YES = TRUE; const BOOL TAKE_FOCUS_NO = FALSE; class LLFocusableElement { friend class LLFocusMgr; // allow access to focus change handlers public: LLFocusableElement(); virtual ~LLFocusableElement(); virtual void setFocus( BOOL b ); virtual BOOL hasFocus() const; typedef boost::function focus_callback_t; void setFocusLostCallback(focus_callback_t cb, void* user_data = NULL) { mFocusLostCallback = cb; mFocusCallbackUserData = user_data; } void setFocusReceivedCallback(focus_callback_t cb, void* user_data = NULL) { mFocusReceivedCallback = cb; mFocusCallbackUserData = user_data; } void setFocusChangedCallback(focus_callback_t cb, void* user_data = NULL ) { mFocusChangedCallback = cb; mFocusCallbackUserData = user_data; } void setTopLostCallback(focus_callback_t cb, void* user_data = NULL ) { mTopLostCallback = cb; mFocusCallbackUserData = user_data; } protected: virtual void onFocusReceived(); virtual void onFocusLost(); virtual void onTopLost(); // called when registered as top ctrl and user clicks elsewhere focus_callback_t mFocusLostCallback; focus_callback_t mFocusReceivedCallback; focus_callback_t mFocusChangedCallback; focus_callback_t mTopLostCallback; void* mFocusCallbackUserData; }; class LLUICtrl : public LLView, public LLFocusableElement, public boost::signals2::trackable { public: typedef boost::function commit_callback_t; typedef boost::signals2::signal commit_signal_t; // *TODO: add xml support for this type of signal in the future typedef boost::signals2::signal mouse_signal_t; typedef boost::function enable_callback_t; typedef boost::signals2::signal enable_signal_t; struct CallbackParam : public LLInitParam::Block { Ignored name; Optional function_name; Optional parameter; Optional control_name; CallbackParam() : name("name"), function_name("function"), parameter("parameter"), control_name("control") // Shortcut to control -> "control_name" for backwards compatability { addSynonym(parameter, "userdata"); } }; struct CommitCallbackParam : public LLInitParam::Block { Optional function; }; struct EnableCallbackParam : public LLInitParam::Block { Optional function; }; struct EnableControls : public LLInitParam::Choice { Alternative enabled; Alternative disabled; EnableControls() : enabled("enabled_control"), disabled("disabled_control") {} }; struct ControlVisibility : public LLInitParam::Choice { Alternative visible; Alternative invisible; ControlVisibility() : visible("visiblity_control"), invisible("invisiblity_control") {} }; struct Params : public LLInitParam::Block { Optional label; Optional tab_stop; Optional initial_value; Optional init_callback, commit_callback; Optional validate_callback; Optional mouseenter_callback; Optional mouseleave_callback; Optional focus_lost_callback; Optional control_name; Optional enabled_controls; Optional controls_visibility; Params(); }; /*virtual*/ ~LLUICtrl(); void initFromParams(const Params& p); protected: friend class LLUICtrlFactory; static const Params& getDefaultParams(); LLUICtrl(const Params& p = getDefaultParams(), const LLViewModelPtr& viewmodel=LLViewModelPtr(new LLViewModel)); void initCommitCallback(const CommitCallbackParam& cb, commit_signal_t& sig); void initEnableCallback(const EnableCallbackParam& cb, enable_signal_t& sig); // 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&); public: // LLView interface /*virtual*/ BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); /*virtual*/ void onFocusReceived(); /*virtual*/ void onFocusLost(); /*virtual*/ void onTopLost(); /*virtual*/ BOOL isCtrl() const; /*virtual*/ void setTentative(BOOL b); /*virtual*/ BOOL getTentative() const; /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask); /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); // From LLFocusableElement /*virtual*/ void setFocus( BOOL b ); /*virtual*/ BOOL hasFocus() const; // New virtuals // Return NULL by default (overrride if the class has the appropriate interface) virtual class LLCtrlSelectionInterface* getSelectionInterface(); virtual class LLCtrlListInterface* getListInterface(); virtual class LLCtrlScrollInterface* getScrollInterface(); bool setControlValue(const LLSD& value); void setControlVariable(LLControlVariable* control); virtual void setControlName(const std::string& control, LLView *context = NULL); LLControlVariable* getControlVariable() { return mControlVariable; } void setEnabledControlVariable(LLControlVariable* control); void setDisabledControlVariable(LLControlVariable* control); void setMakeVisibleControlVariable(LLControlVariable* control); void setMakeInvisibleControlVariable(LLControlVariable* control); virtual void setValue(const LLSD& value); virtual LLSD getValue() const; /// When two widgets are displaying the same data (e.g. during a skin /// change), share their ViewModel. virtual void shareViewModelFrom(const LLUICtrl& other); virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text ); virtual void setIsChrome(BOOL is_chrome); virtual BOOL acceptsTextInput() const; // Defaults to false // A control is dirty if the user has modified its value. // Editable controls should override this. virtual BOOL isDirty() const; // Defauls to false virtual void resetDirty(); //Defaults to no-op // Call appropriate callback virtual void onCommit(); // Default to no-op: virtual void onTabInto(); virtual void clear(); virtual void setColor(const LLColor4& color); BOOL focusNextItem(BOOL text_entry_only); BOOL focusPrevItem(BOOL text_entry_only); BOOL focusFirstItem(BOOL prefer_text_fields = FALSE, BOOL focus_flash = TRUE ); BOOL focusLastItem(BOOL prefer_text_fields = FALSE); // Non Virtuals LLHandle getUICtrlHandle() const { return mUICtrlHandle; } BOOL getIsChrome() const; void setTabStop( BOOL b ); BOOL hasTabStop() const; LLUICtrl* getParentUICtrl() const; boost::signals2::connection setCommitCallback( const commit_signal_t::slot_type& cb ) { return mCommitSignal.connect(cb); } boost::signals2::connection setValidateCallback( const enable_signal_t::slot_type& cb ) { return mValidateSignal.connect(cb); } boost::signals2::connection setMouseEnterCallback( const commit_signal_t::slot_type& cb ) { return mMouseEnterSignal.connect(cb); } boost::signals2::connection setMouseLeaveCallback( const commit_signal_t::slot_type& cb ) { return mMouseLeaveSignal.connect(cb); } boost::signals2::connection setMouseDownCallback( const mouse_signal_t::slot_type& cb ) { return mMouseDownSignal.connect(cb); } boost::signals2::connection setMouseUpCallback( const mouse_signal_t::slot_type& cb ) { return mMouseUpSignal.connect(cb); } boost::signals2::connection setRightClickedCallback( const mouse_signal_t::slot_type& cb ) { return mRightClickSignal.connect(cb); } // *TODO: Deprecate; for backwards compatability only: boost::signals2::connection setCommitCallback( boost::function cb, void* data); boost::signals2::connection setValidateBeforeCommit( boost::function cb ); LLUICtrl* findRootMostFocusRoot(); class LLTextInputFilter : public LLQueryFilter, public LLSingleton { /*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const { return filterResult_t(view->isCtrl() && static_cast(view)->acceptsTextInput(), TRUE); } }; template class CallbackRegistry : public LLRegistrySingleton {}; class CommitCallbackRegistry : public CallbackRegistry{}; class EnableCallbackRegistry : public CallbackRegistry{}; protected: static bool controlListener(const LLSD& newvalue, LLHandle handle, std::string type); commit_signal_t mCommitSignal; enable_signal_t mValidateSignal; commit_signal_t mMouseEnterSignal; commit_signal_t mMouseLeaveSignal; mouse_signal_t mMouseDownSignal; mouse_signal_t mMouseUpSignal; mouse_signal_t mRightClickSignal; LLViewModelPtr mViewModel; LLControlVariable* mControlVariable; boost::signals2::connection mControlConnection; LLControlVariable* mEnabledControlVariable; boost::signals2::connection mEnabledControlConnection; LLControlVariable* mDisabledControlVariable; boost::signals2::connection mDisabledControlConnection; LLControlVariable* mMakeVisibleControlVariable; boost::signals2::connection mMakeVisibleControlConnection; LLControlVariable* mMakeInvisibleControlVariable; boost::signals2::connection mMakeInvisibleControlConnection; private: BOOL mTabStop; BOOL mIsChrome; BOOL mTentative; LLRootHandle mUICtrlHandle; class DefaultTabGroupFirstSorter; }; namespace LLInitParam { template<> bool ParamCompare::equals( const LLUICtrl::commit_callback_t &a, const LLUICtrl::commit_callback_t &b); template<> bool ParamCompare::equals( const LLUICtrl::enable_callback_t &a, const LLUICtrl::enable_callback_t &b); template<> bool ParamCompare::equals( const LLUICtrl::focus_callback_t &a, const LLUICtrl::focus_callback_t &b); template<> bool ParamCompare >::equals( const LLLazyValue &a, const LLLazyValue &b); } #endif // LL_LLUICTRL_H