aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llui/lluictrl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llui/lluictrl.cpp')
-rw-r--r--linden/indra/llui/lluictrl.cpp203
1 files changed, 141 insertions, 62 deletions
diff --git a/linden/indra/llui/lluictrl.cpp b/linden/indra/llui/lluictrl.cpp
index 61d6c8c..63db1cc 100644
--- a/linden/indra/llui/lluictrl.cpp
+++ b/linden/indra/llui/lluictrl.cpp
@@ -13,12 +13,12 @@
13 * ("GPL"), unless you have obtained a separate licensing agreement 13 * ("GPL"), unless you have obtained a separate licensing agreement
14 * ("Other License"), formally executed by you and Linden Lab. Terms of 14 * ("Other License"), formally executed by you and Linden Lab. Terms of
15 * the GPL can be found in doc/GPL-license.txt in this distribution, or 15 * the GPL can be found in doc/GPL-license.txt in this distribution, or
16 * online at http://secondlife.com/developers/opensource/gplv2 16 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
17 * 17 *
18 * There are special exceptions to the terms and conditions of the GPL as 18 * There are special exceptions to the terms and conditions of the GPL as
19 * it is applied to this Source Code. View the full text of the exception 19 * it is applied to this Source Code. View the full text of the exception
20 * in the file doc/FLOSS-exception.txt in this software distribution, or 20 * in the file doc/FLOSS-exception.txt in this software distribution, or
21 * online at http://secondlife.com/developers/opensource/flossexception 21 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
22 * 22 *
23 * By copying, modifying or distributing this software, you acknowledge 23 * By copying, modifying or distributing this software, you acknowledge
24 * that you have read and understood your obligations described above, 24 * that you have read and understood your obligations described above,
@@ -47,11 +47,53 @@
47 47
48const U32 MAX_STRING_LENGTH = 10; 48const U32 MAX_STRING_LENGTH = 10;
49 49
50LLUICtrl::LLUICtrl() : 50LLFocusableElement::LLFocusableElement()
51 mCommitCallback(NULL), 51: mFocusLostCallback(NULL),
52 mFocusLostCallback(NULL),
53 mFocusReceivedCallback(NULL), 52 mFocusReceivedCallback(NULL),
54 mFocusChangedCallback(NULL), 53 mFocusChangedCallback(NULL),
54 mFocusCallbackUserData(NULL)
55{
56}
57
58void LLFocusableElement::onFocusReceived()
59{
60 if( mFocusReceivedCallback )
61 {
62 mFocusReceivedCallback( this, mFocusCallbackUserData );
63 }
64 if( mFocusChangedCallback )
65 {
66 mFocusChangedCallback( this, mFocusCallbackUserData );
67 }
68}
69
70void LLFocusableElement::onFocusLost()
71{
72 if( mFocusLostCallback )
73 {
74 mFocusLostCallback( this, mFocusCallbackUserData );
75 }
76
77 if( mFocusChangedCallback )
78 {
79 mFocusChangedCallback( this, mFocusCallbackUserData );
80 }
81}
82
83BOOL LLFocusableElement::hasFocus() const
84{
85 return FALSE;
86}
87
88void LLFocusableElement::setFocus(BOOL b)
89{
90}
91
92
93
94LLUICtrl::LLUICtrl() :
95 mCommitCallback(NULL),
96 mLostTopCallback(NULL),
55 mValidateCallback(NULL), 97 mValidateCallback(NULL),
56 mCallbackUserData(NULL), 98 mCallbackUserData(NULL),
57 mTentative(FALSE), 99 mTentative(FALSE),
@@ -68,9 +110,7 @@ LLUICtrl::LLUICtrl(const LLString& name, const LLRect& rect, BOOL mouse_opaque,
68 // of buttons in the UI. JC 7/20/2002 110 // of buttons in the UI. JC 7/20/2002
69 LLView( name, rect, mouse_opaque, reshape ), 111 LLView( name, rect, mouse_opaque, reshape ),
70 mCommitCallback( on_commit_callback) , 112 mCommitCallback( on_commit_callback) ,
71 mFocusLostCallback( NULL ), 113 mLostTopCallback( NULL ),
72 mFocusReceivedCallback( NULL ),
73 mFocusChangedCallback( NULL ),
74 mValidateCallback( NULL ), 114 mValidateCallback( NULL ),
75 mCallbackUserData( callback_userdata ), 115 mCallbackUserData( callback_userdata ),
76 mTentative( FALSE ), 116 mTentative( FALSE ),
@@ -128,6 +168,86 @@ LLCtrlScrollInterface* LLUICtrl::getScrollInterface()
128 return NULL; 168 return NULL;
129} 169}
130 170
171BOOL LLUICtrl::hasFocus() const
172{
173 return (gFocusMgr.childHasKeyboardFocus(this));
174}
175
176void LLUICtrl::setFocus(BOOL b)
177{
178 // focus NEVER goes to ui ctrls that are disabled!
179 if (!mEnabled)
180 {
181 return;
182 }
183 if( b )
184 {
185 if (!hasFocus())
186 {
187 gFocusMgr.setKeyboardFocus( this );
188 }
189 }
190 else
191 {
192 if( gFocusMgr.childHasKeyboardFocus(this))
193 {
194 gFocusMgr.setKeyboardFocus( NULL );
195 }
196 }
197}
198
199void LLUICtrl::onFocusReceived()
200{
201 // trigger callbacks
202 LLFocusableElement::onFocusReceived();
203
204 // find first view in hierarchy above new focus that is a LLUICtrl
205 LLView* viewp = getParent();
206 LLUICtrl* last_focus = gFocusMgr.getLastKeyboardFocus();
207
208 while (viewp && !viewp->isCtrl())
209 {
210 viewp = viewp->getParent();
211 }
212
213 // and if it has newly gained focus, call onFocusReceived()
214 LLUICtrl* ctrlp = static_cast<LLUICtrl*>(viewp);
215 if (ctrlp && (!last_focus || !last_focus->hasAncestor(ctrlp)))
216 {
217 ctrlp->onFocusReceived();
218 }
219}
220
221void LLUICtrl::onFocusLost()
222{
223 // trigger callbacks
224 LLFocusableElement::onFocusLost();
225
226 // find first view in hierarchy above old focus that is a LLUICtrl
227 LLView* viewp = getParent();
228 while (viewp && !viewp->isCtrl())
229 {
230 viewp = viewp->getParent();
231 }
232
233 // and if it has just lost focus, call onFocusReceived()
234 LLUICtrl* ctrlp = static_cast<LLUICtrl*>(viewp);
235 // hasFocus() includes any descendants
236 if (ctrlp && !ctrlp->hasFocus())
237 {
238 ctrlp->onFocusLost();
239 }
240}
241
242void LLUICtrl::onLostTop()
243{
244 if (mLostTopCallback)
245 {
246 mLostTopCallback(this, mCallbackUserData);
247 }
248}
249
250
131// virtual 251// virtual
132void LLUICtrl::setTabStop( BOOL b ) 252void LLUICtrl::setTabStop( BOOL b )
133{ 253{
@@ -165,68 +285,26 @@ void LLUICtrl::setIsChrome(BOOL is_chrome)
165// virtual 285// virtual
166BOOL LLUICtrl::getIsChrome() const 286BOOL LLUICtrl::getIsChrome() const
167{ 287{
168 return mIsChrome; 288 // am I or any of my ancestors flagged as "chrome"?
169} 289 if (mIsChrome) return TRUE;
170 290
171void LLUICtrl::onFocusReceived() 291 LLView* parent_ctrl = getParent();
172{ 292 while(parent_ctrl)
173 if( mFocusReceivedCallback )
174 {
175 mFocusReceivedCallback( this, mCallbackUserData );
176 }
177 if( mFocusChangedCallback )
178 { 293 {
179 mFocusChangedCallback( this, mCallbackUserData ); 294 if(parent_ctrl->isCtrl())
180 }
181}
182
183void LLUICtrl::onFocusLost()
184{
185 if( mFocusLostCallback )
186 {
187 mFocusLostCallback( this, mCallbackUserData );
188 }
189
190 if( mFocusChangedCallback )
191 {
192 mFocusChangedCallback( this, mCallbackUserData );
193 }
194}
195
196BOOL LLUICtrl::hasFocus() const
197{
198 return (gFocusMgr.childHasKeyboardFocus(this));
199}
200
201void LLUICtrl::setFocus(BOOL b)
202{
203 // focus NEVER goes to ui ctrls that are disabled!
204 if (!mEnabled)
205 {
206 return;
207 }
208 if( b )
209 {
210 if (!hasFocus())
211 { 295 {
212 gFocusMgr.setKeyboardFocus( this, &LLUICtrl::onFocusLostCallback ); 296 break;
213 onFocusReceived();
214 } 297 }
298 parent_ctrl = parent_ctrl->getParent();
215 } 299 }
216 else 300
301 if(parent_ctrl)
217 { 302 {
218 if( gFocusMgr.childHasKeyboardFocus(this)) 303 // recurse into parent_ctrl and ask if it is in a chrome subtree
219 { 304 return ((LLUICtrl*)parent_ctrl)->getIsChrome();
220 gFocusMgr.setKeyboardFocus( NULL, NULL );
221 onFocusLost();
222 }
223 } 305 }
224}
225 306
226// static 307 return FALSE;
227void LLUICtrl::onFocusLostCallback( LLUICtrl* old_focus )
228{
229 old_focus->onFocusLost();
230} 308}
231 309
232// this comparator uses the crazy disambiguating logic of LLCompareByTabOrder, 310// this comparator uses the crazy disambiguating logic of LLCompareByTabOrder,
@@ -262,6 +340,7 @@ public:
262 } 340 }
263}; 341};
264 342
343
265BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields) 344BOOL LLUICtrl::focusFirstItem(BOOL prefer_text_fields)
266{ 345{
267 // try to select default tab group child 346 // try to select default tab group child