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 { }