00001 
00033 
00034 #include "linden_common.h"
00035 
00036 #include "lluictrl.h"
00037 
00038 #include "llgl.h"
00039 #include "llui.h"
00040 #include "lluiconstants.h"
00041 #include "llfocusmgr.h"
00042 #include "v3color.h"
00043 
00044 #include "llstring.h"
00045 #include "llfontgl.h"
00046 #include "llkeyboard.h"
00047 
00048 const U32 MAX_STRING_LENGTH = 10;
00049 
00050 LLUICtrl::LLUICtrl() :
00051         mCommitCallback(NULL),
00052         mFocusLostCallback(NULL),
00053         mFocusReceivedCallback(NULL),
00054         mFocusChangedCallback(NULL),
00055         mValidateCallback(NULL),
00056         mCallbackUserData(NULL),
00057         mTentative(FALSE),
00058         mTabStop(TRUE),
00059         mIsChrome(FALSE)
00060 {
00061 }
00062 
00063 LLUICtrl::LLUICtrl(const LLString& name, const LLRect& rect, BOOL mouse_opaque,
00064         void (*on_commit_callback)(LLUICtrl*, void*),
00065         void* callback_userdata,
00066         U32 reshape)
00067 :       
00068         
00069         LLView( name, rect, mouse_opaque, reshape ),
00070         mCommitCallback( on_commit_callback) ,
00071         mFocusLostCallback( NULL ),
00072         mFocusReceivedCallback( NULL ),
00073         mFocusChangedCallback( NULL ),
00074         mValidateCallback( NULL ),
00075         mCallbackUserData( callback_userdata ),
00076         mTentative( FALSE ),
00077         mTabStop( TRUE ),
00078         mIsChrome(FALSE)
00079 {
00080 }
00081 
00082 LLUICtrl::~LLUICtrl()
00083 {
00084         gFocusMgr.releaseFocusIfNeeded( this ); 
00085 
00086         if( gFocusMgr.getTopCtrl() == this )
00087         {
00088                 llwarns << "UI Control holding top ctrl deleted: " << getName() << ".  Top view removed." << llendl;
00089                 gFocusMgr.removeTopCtrlWithoutCallback( this );
00090         }
00091 }
00092 
00093 void LLUICtrl::onCommit()
00094 {
00095         if( mCommitCallback )
00096         {
00097                 mCommitCallback( this, mCallbackUserData );
00098         }
00099 }
00100 
00101 
00102 BOOL LLUICtrl::setTextArg( const LLString& key, const LLStringExplicit& text ) 
00103 { 
00104         return FALSE; 
00105 }
00106 
00107 
00108 BOOL LLUICtrl::setLabelArg( const LLString& key, const LLStringExplicit& text ) 
00109 { 
00110         return FALSE; 
00111 }
00112 
00113 
00114 LLCtrlSelectionInterface* LLUICtrl::getSelectionInterface()     
00115 { 
00116         return NULL; 
00117 }
00118 
00119 
00120 LLCtrlListInterface* LLUICtrl::getListInterface()                               
00121 { 
00122         return NULL; 
00123 }
00124 
00125 
00126 LLCtrlScrollInterface* LLUICtrl::getScrollInterface()                   
00127 { 
00128         return NULL; 
00129 }
00130 
00131 
00132 void LLUICtrl::setTabStop( BOOL b )     
00133 { 
00134         mTabStop = b;
00135 }
00136 
00137 
00138 BOOL LLUICtrl::hasTabStop() const               
00139 { 
00140         return mTabStop;
00141 }
00142 
00143 
00144 BOOL LLUICtrl::acceptsTextInput() const
00145 { 
00146         return FALSE; 
00147 }
00148 
00149 
00150 void LLUICtrl::onTabInto()                              
00151 {
00152 }
00153 
00154 
00155 void LLUICtrl::clear()                                  
00156 {
00157 }
00158 
00159 
00160 void LLUICtrl::setIsChrome(BOOL is_chrome)
00161 {
00162         mIsChrome = is_chrome; 
00163 }
00164 
00165 
00166 BOOL LLUICtrl::getIsChrome() const
00167 { 
00168         return mIsChrome; 
00169 }
00170 
00171 void LLUICtrl::onFocusReceived()
00172 {
00173         if( mFocusReceivedCallback )
00174         {
00175                 mFocusReceivedCallback( this, mCallbackUserData );
00176         }
00177         if( mFocusChangedCallback )
00178         {
00179                 mFocusChangedCallback( this, mCallbackUserData );
00180         }
00181 }
00182 
00183 void LLUICtrl::onFocusLost()
00184 {
00185         if( mFocusLostCallback )
00186         {
00187                 mFocusLostCallback( this, mCallbackUserData );
00188         }
00189 
00190         if( mFocusChangedCallback )
00191         {
00192                 mFocusChangedCallback( this, mCallbackUserData );
00193         }
00194 }
00195 
00196 BOOL LLUICtrl::hasFocus() const
00197 {
00198         return (gFocusMgr.childHasKeyboardFocus(this));
00199 }
00200 
00201 void LLUICtrl::setFocus(BOOL b)
00202 {
00203         
00204         if (!mEnabled)
00205         {
00206                 return;
00207         }
00208         if( b )
00209         {
00210                 if (!hasFocus())
00211                 {
00212                         gFocusMgr.setKeyboardFocus( this, &LLUICtrl::onFocusLostCallback );
00213                         onFocusReceived();
00214                 }
00215         }
00216         else
00217         {
00218                 if( gFocusMgr.childHasKeyboardFocus(this))
00219                 {
00220                         gFocusMgr.setKeyboardFocus( NULL, NULL );
00221                         onFocusLost();
00222                 }
00223         }
00224 }
00225 
00226 
00227 void LLUICtrl::onFocusLostCallback( LLUICtrl* old_focus )
00228 {
00229         old_focus->onFocusLost();
00230 }
00231 
00232 
00233 
00234 
00235 class CompareByDefaultTabGroup: public LLCompareByTabOrder
00236 {
00237 public:
00238         CompareByDefaultTabGroup(LLView::child_tab_order_t order, S32 default_tab_group):
00239                         LLCompareByTabOrder(order),
00240                         mDefaultTabGroup(default_tab_group) {}
00241 protected:
00242          bool compareTabOrders(const LLView::tab_order_t & a, const LLView::tab_order_t & b) const
00243         {
00244                 S32 ag = a.first; 
00245                 S32 bg = b.first; 
00246                 
00247                 
00248                 if(ag < mDefaultTabGroup && bg >= mDefaultTabGroup) return false;
00249                 if(bg < mDefaultTabGroup && ag >= mDefaultTabGroup) return true;
00250                 return a < b;  
00251         }
00252         S32 mDefaultTabGroup;
00253 };
00254 
00255 
00256 class DefaultTabGroupFirstSorter : public LLQuerySorter, public LLSingleton<DefaultTabGroupFirstSorter>
00257 {
00258 public:
00259          void operator() (LLView * parent, viewList_t &children) const
00260         {
00261                 children.sort(CompareByDefaultTabGroup(parent->getCtrlOrder(), parent->getDefaultTabGroup()));
00262         }
00263 };
00264 
00265 BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields)
00266 {
00267         
00268         LLCtrlQuery query = LLView::getTabOrderQuery();
00269         
00270         query.setSorter(DefaultTabGroupFirstSorter::getInstance());
00271         LLView::child_list_t result = query(this);
00272         if(result.size() > 0)
00273         {
00274                 LLUICtrl * ctrl = static_cast<LLUICtrl*>(result.front());
00275                 if(!ctrl->hasFocus())
00276                 {
00277                         ctrl->setFocus(TRUE);
00278                         ctrl->onTabInto();  
00279                         gFocusMgr.triggerFocusFlash();
00280                 }
00281                 return TRUE;
00282         }       
00283         
00284         return LLView::focusFirstItem(prefer_text_fields);
00285 }
00286 
00287 
00288 
00289 
00290 
00291 
00292 
00293 
00294 
00295 
00296 
00297 
00298 
00299 
00300 
00301 
00302 
00303 
00304 
00305 
00306 
00307 
00308 
00309 
00310 
00311 
00312 
00313 
00314 
00315 
00316 
00317 
00318 void LLUICtrl::initFromXML(LLXMLNodePtr node, LLView* parent)
00319 {
00320         BOOL has_tab_stop = hasTabStop();
00321         node->getAttributeBOOL("tab_stop", has_tab_stop);
00322 
00323         setTabStop(has_tab_stop);
00324 
00325         LLView::initFromXML(node, parent);
00326 }
00327 
00328 LLXMLNodePtr LLUICtrl::getXML(bool save_children) const
00329 {
00330         LLXMLNodePtr node = LLView::getXML(save_children);
00331         node->createChild("tab_stop", TRUE)->setBoolValue(hasTabStop());
00332 
00333         return node;
00334 }
00335 
00336 
00337 
00338 LLPanel* LLUICtrl::getParentPanel() const
00339 {
00340         LLView* parent = getParent();
00341         while (parent 
00342                    && parent->getWidgetType() != WIDGET_TYPE_PANEL
00343                    && parent->getWidgetType() != WIDGET_TYPE_FLOATER)
00344         {
00345                 parent = parent->getParent();
00346         }
00347         return reinterpret_cast<LLPanel*>(parent);
00348 }
00349 
00350 
00351 void LLUICtrl::setTentative(BOOL b)                                                                     
00352 { 
00353         mTentative = b; 
00354 }
00355 
00356 
00357 BOOL LLUICtrl::getTentative() const                                                                     
00358 { 
00359         return mTentative; 
00360 }
00361 
00362 
00363 void LLUICtrl::setDoubleClickCallback( void (*cb)(void*) )                              
00364 { 
00365 }
00366 
00367 
00368 void LLUICtrl::setColor(const LLColor4& color)                                                  
00369 { }
00370 
00371 
00372 void LLUICtrl::setMinValue(LLSD min_value)                                                              
00373 { }
00374 
00375 
00376 void LLUICtrl::setMaxValue(LLSD max_value)                                                              
00377 { }