aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llui/llfocusmgr.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llui/llfocusmgr.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to '')
-rw-r--r--linden/indra/llui/llfocusmgr.cpp388
1 files changed, 388 insertions, 0 deletions
diff --git a/linden/indra/llui/llfocusmgr.cpp b/linden/indra/llui/llfocusmgr.cpp
new file mode 100644
index 0000000..f02996b
--- /dev/null
+++ b/linden/indra/llui/llfocusmgr.cpp
@@ -0,0 +1,388 @@
1/**
2 * @file llfocusmgr.cpp
3 * @brief LLFocusMgr base class
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "linden_common.h"
29
30#include "llfocusmgr.h"
31#include "lluictrl.h"
32#include "v4color.h"
33
34const F32 FOCUS_FADE_TIME = 0.3f;
35
36LLFocusMgr gFocusMgr;
37
38LLFocusMgr::LLFocusMgr()
39 :
40 mLockedView( NULL ),
41 mKeyboardLockedFocusLostCallback( NULL ),
42 mMouseCaptor( NULL ),
43 mMouseCaptureLostCallback( NULL ),
44 mKeyboardFocus( NULL ),
45 mDefaultKeyboardFocus( NULL ),
46 mKeyboardFocusLostCallback( NULL ),
47 mTopView( NULL ),
48 mTopViewLostCallback( NULL ),
49 mFocusWeight(0.f),
50 mAppHasFocus(TRUE) // Macs don't seem to notify us that we've gotten focus, so default to true
51 #ifdef _DEBUG
52 , mMouseCaptorName("none")
53 , mKeyboardFocusName("none")
54 , mTopViewName("none")
55 #endif
56{
57}
58
59LLFocusMgr::~LLFocusMgr()
60{
61 mFocusHistory.clear();
62}
63
64void LLFocusMgr::releaseFocusIfNeeded( LLView* view )
65{
66 if( childHasMouseCapture( view ) )
67 {
68 setMouseCapture( NULL, NULL );
69 }
70
71 if( childHasKeyboardFocus( view ))
72 {
73 if (view == mLockedView)
74 {
75 mLockedView = NULL;
76 mKeyboardLockedFocusLostCallback = NULL;
77 setKeyboardFocus( NULL, NULL );
78 }
79 else
80 {
81 setKeyboardFocus( mLockedView, mKeyboardLockedFocusLostCallback );
82 }
83 }
84
85 if( childIsTopView( view ) )
86 {
87 setTopView( NULL, NULL );
88 }
89}
90
91
92void LLFocusMgr::setKeyboardFocus(LLUICtrl* new_focus, FocusLostCallback on_focus_lost, BOOL lock)
93{
94 if (mLockedView &&
95 (new_focus == NULL ||
96 (new_focus != mLockedView && !new_focus->hasAncestor(mLockedView))))
97 {
98 // don't allow focus to go to anything that is not the locked focus
99 // or one of its descendants
100 return;
101 }
102 FocusLostCallback old_callback = mKeyboardFocusLostCallback;
103 mKeyboardFocusLostCallback = on_focus_lost;
104
105 //llinfos << "Keyboard focus handled by " << (new_focus ? new_focus->getName() : "nothing") << llendl;
106
107 if( new_focus != mKeyboardFocus )
108 {
109 LLUICtrl* old_focus = mKeyboardFocus;
110 mKeyboardFocus = new_focus;
111
112 // clear out any existing flash
113 if (new_focus)
114 {
115 mFocusWeight = 0.f;
116 }
117 mFocusTimer.reset();
118
119 if( old_callback )
120 {
121 old_callback( old_focus );
122 }
123
124 #ifdef _DEBUG
125 mKeyboardFocusName = new_focus ? new_focus->getName() : "none";
126 #endif
127
128 // If we've got a default keyboard focus, and the caller is
129 // releasing keyboard focus, move to the default.
130 if (mDefaultKeyboardFocus != NULL && new_focus == NULL)
131 {
132 mDefaultKeyboardFocus->setFocus(TRUE);
133 }
134
135 LLView* focus_subtree = new_focus;
136 LLView* viewp = new_focus;
137 // find root-most focus root
138 while(viewp)
139 {
140 if (viewp->isFocusRoot())
141 {
142 focus_subtree = viewp;
143 }
144 viewp = viewp->getParent();
145 }
146
147
148 if (focus_subtree)
149 {
150 mFocusHistory[focus_subtree->mViewHandle] = new_focus ? new_focus->mViewHandle : LLViewHandle::sDeadHandle;
151 }
152 }
153
154 if (lock)
155 {
156 mLockedView = new_focus;
157 mKeyboardLockedFocusLostCallback = on_focus_lost;
158 }
159}
160
161void LLFocusMgr::setDefaultKeyboardFocus(LLUICtrl* default_focus)
162{
163 mDefaultKeyboardFocus = default_focus;
164}
165
166// Returns TRUE is parent or any descedent of parent has keyboard focus.
167BOOL LLFocusMgr::childHasKeyboardFocus(const LLView* parent ) const
168{
169 LLView* focus_view = mKeyboardFocus;
170 while( focus_view )
171 {
172 if( focus_view == parent )
173 {
174 return TRUE;
175 }
176 focus_view = focus_view->getParent();
177 }
178 return FALSE;
179}
180
181// Returns TRUE is parent or any descedent of parent is the mouse captor.
182BOOL LLFocusMgr::childHasMouseCapture( LLView* parent )
183{
184 if( mMouseCaptor && mMouseCaptor->isView() )
185 {
186 LLView* captor_view = (LLView*)mMouseCaptor;
187 while( captor_view )
188 {
189 if( captor_view == parent )
190 {
191 return TRUE;
192 }
193 captor_view = captor_view->getParent();
194 }
195 }
196 return FALSE;
197}
198
199void LLFocusMgr::removeKeyboardFocusWithoutCallback( LLView* focus )
200{
201 // should be ok to unlock here, as you have to know the locked view
202 // in order to unlock it
203 if (focus == mLockedView)
204 {
205 mLockedView = NULL;
206 mKeyboardLockedFocusLostCallback = NULL;
207 }
208
209 if( mKeyboardFocus == focus )
210 {
211 mKeyboardFocus = NULL;
212 mKeyboardFocusLostCallback = NULL;
213 #ifdef _DEBUG
214 mKeyboardFocusName = "none";
215 #endif
216 }
217}
218
219
220void LLFocusMgr::setMouseCapture( LLMouseHandler* new_captor, void (*on_capture_lost)(LLMouseHandler* old_captor) )
221{
222 //if (mFocusLocked)
223 //{
224 // return;
225 //}
226
227 void (*old_callback)(LLMouseHandler*) = mMouseCaptureLostCallback;
228 mMouseCaptureLostCallback = on_capture_lost;
229
230 if( new_captor != mMouseCaptor )
231 {
232 LLMouseHandler* old_captor = mMouseCaptor;
233 mMouseCaptor = new_captor;
234 /*
235 if (new_captor)
236 {
237 if ( new_captor->getName() == "Stickto")
238 {
239 llinfos << "New mouse captor: " << new_captor->getName() << llendl;
240 }
241 else
242 {
243 llinfos << "New mouse captor: " << new_captor->getName() << llendl;
244 }
245 }
246 else
247 {
248 llinfos << "New mouse captor: NULL" << llendl;
249 }
250 */
251
252 if( old_callback )
253 {
254 old_callback( old_captor );
255 }
256
257 #ifdef _DEBUG
258 mMouseCaptorName = new_captor ? new_captor->getName() : "none";
259 #endif
260 }
261}
262
263void LLFocusMgr::removeMouseCaptureWithoutCallback( LLMouseHandler* captor )
264{
265 //if (mFocusLocked)
266 //{
267 // return;
268 //}
269 if( mMouseCaptor == captor )
270 {
271 mMouseCaptor = NULL;
272 mMouseCaptureLostCallback = NULL;
273 #ifdef _DEBUG
274 mMouseCaptorName = "none";
275 #endif
276 }
277}
278
279
280BOOL LLFocusMgr::childIsTopView( LLView* parent )
281{
282 LLView* top_view = mTopView;
283 while( top_view )
284 {
285 if( top_view == parent )
286 {
287 return TRUE;
288 }
289 top_view = top_view->getParent();
290 }
291 return FALSE;
292}
293
294
295
296// set new_top = NULL to release top_view.
297void LLFocusMgr::setTopView( LLView* new_top, void (*on_top_lost)(LLView* old_top) )
298{
299 void (*old_callback)(LLView*) = mTopViewLostCallback;
300 mTopViewLostCallback = on_top_lost;
301
302 if( new_top != mTopView )
303 {
304 LLView* old_top = mTopView;
305 mTopView = new_top;
306 if( old_callback )
307 {
308 old_callback( old_top );
309 }
310
311 mTopView = new_top;
312
313 #ifdef _DEBUG
314 mTopViewName = new_top ? new_top->getName() : "none";
315 #endif
316 }
317}
318
319void LLFocusMgr::removeTopViewWithoutCallback( LLView* top_view )
320{
321 if( mTopView == top_view )
322 {
323 mTopView = NULL;
324 mTopViewLostCallback = NULL;
325 #ifdef _DEBUG
326 mTopViewName = "none";
327 #endif
328 }
329}
330
331void LLFocusMgr::unlockFocus()
332{
333 mLockedView = NULL;
334 mKeyboardLockedFocusLostCallback = NULL;
335}
336
337F32 LLFocusMgr::getFocusFlashAmt()
338{
339 return clamp_rescale(getFocusTime(), 0.f, FOCUS_FADE_TIME, mFocusWeight, 0.f);
340}
341
342LLColor4 LLFocusMgr::getFocusColor()
343{
344 LLColor4 focus_color = lerp(LLUI::sColorsGroup->getColor( "FocusColor" ), LLColor4::white, getFocusFlashAmt());
345 // de-emphasize keyboard focus when app has lost focus (to avoid typing into wrong window problem)
346 if (!mAppHasFocus)
347 {
348 focus_color.mV[VALPHA] *= 0.4f;
349 }
350 return focus_color;
351}
352
353void LLFocusMgr::triggerFocusFlash()
354{
355 mFocusTimer.reset();
356 mFocusWeight = 1.f;
357}
358
359void LLFocusMgr::setAppHasFocus(BOOL focus)
360{
361 if (!mAppHasFocus && focus)
362 {
363 triggerFocusFlash();
364 }
365 mAppHasFocus = focus;
366}
367
368LLUICtrl* LLFocusMgr::getLastFocusForGroup(LLView* subtree_root)
369{
370 if (subtree_root)
371 {
372 focus_history_map_t::iterator found_it = mFocusHistory.find(subtree_root->mViewHandle);
373 if (found_it != mFocusHistory.end())
374 {
375 // found last focus for this subtree
376 return static_cast<LLUICtrl*>(LLView::getViewByHandle(found_it->second));
377 }
378 }
379 return NULL;
380}
381
382void LLFocusMgr::clearLastFocusForGroup(LLView* subtree_root)
383{
384 if (subtree_root)
385 {
386 mFocusHistory.erase(subtree_root->mViewHandle);
387 }
388}