aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llui/llmodaldialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llui/llmodaldialog.cpp307
1 files changed, 307 insertions, 0 deletions
diff --git a/linden/indra/llui/llmodaldialog.cpp b/linden/indra/llui/llmodaldialog.cpp
new file mode 100644
index 0000000..c875e7c
--- /dev/null
+++ b/linden/indra/llui/llmodaldialog.cpp
@@ -0,0 +1,307 @@
1/**
2 * @file llmodaldialog.cpp
3 * @brief LLModalDialog 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 "llmodaldialog.h"
31
32#include "llfocusmgr.h"
33#include "v4color.h"
34#include "v2math.h"
35#include "llui.h"
36#include "llwindow.h"
37#include "llkeyboard.h"
38
39// static
40std::list<LLModalDialog*> LLModalDialog::sModalStack;
41
42LLModalDialog::LLModalDialog( const LLString& title, S32 width, S32 height, BOOL modal )
43 : LLFloater( "modal container",
44 LLRect( 0, height, width, 0 ),
45 title,
46 FALSE, // resizable
47 DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT,
48 FALSE, // drag_on_left
49 modal ? FALSE : TRUE, // minimizable
50 modal ? FALSE : TRUE, // close button
51 TRUE), // bordered
52 mModal( modal )
53{
54 setVisible( FALSE );
55 setBackgroundVisible(TRUE);
56 setBackgroundOpaque(TRUE);
57 centerOnScreen(); // default position
58}
59
60LLModalDialog::~LLModalDialog()
61{
62 // don't unlock focus unless we have it
63 if (gFocusMgr.childHasKeyboardFocus(this))
64 {
65 gFocusMgr.unlockFocus();
66 }
67}
68
69void LLModalDialog::reshape(S32 width, S32 height, BOOL called_from_parent)
70{
71 LLFloater::reshape(width, height, called_from_parent);
72 centerOnScreen();
73}
74
75void LLModalDialog::startModal()
76{
77 if (mModal)
78 {
79 // If Modal, Hide the active modal dialog
80 if (!sModalStack.empty())
81 {
82 LLModalDialog* front = sModalStack.front();
83 front->setVisible(FALSE);
84 }
85
86 // This is a modal dialog. It sucks up all mouse and keyboard operations.
87 gFocusMgr.setMouseCapture( this, NULL );
88 gFocusMgr.setTopView( this, NULL );
89 setFocus(TRUE);
90
91 sModalStack.push_front( this );
92 }
93
94 setVisible( TRUE );
95}
96
97void LLModalDialog::stopModal()
98{
99 gFocusMgr.unlockFocus();
100 gFocusMgr.releaseFocusIfNeeded( this );
101
102 if (mModal)
103 {
104 std::list<LLModalDialog*>::iterator iter = std::find(sModalStack.begin(), sModalStack.end(), this);
105 if (iter != sModalStack.end())
106 {
107 sModalStack.erase(iter);
108 }
109 else
110 {
111 llwarns << "LLModalDialog::stopModal not in list!" << llendl;
112 }
113 }
114 if (!sModalStack.empty())
115 {
116 LLModalDialog* front = sModalStack.front();
117 front->setVisible(TRUE);
118 }
119}
120
121
122void LLModalDialog::setVisible( BOOL visible )
123{
124 if (mModal)
125 {
126 if( visible )
127 {
128 // This is a modal dialog. It sucks up all mouse and keyboard operations.
129 gFocusMgr.setMouseCapture( this, NULL );
130
131 // The dialog view is a root view
132 gFocusMgr.setTopView( this, NULL );
133 setFocus( TRUE );
134 }
135 else
136 {
137 gFocusMgr.releaseFocusIfNeeded( this );
138 }
139 }
140
141 LLFloater::setVisible( visible );
142}
143
144BOOL LLModalDialog::handleMouseDown(S32 x, S32 y, MASK mask)
145{
146 if (!LLFloater::handleMouseDown(x, y, mask))
147 {
148 if (mModal)
149 {
150 // Click was outside the panel
151 make_ui_sound("UISndInvalidOp");
152 }
153 }
154 return TRUE;
155}
156
157BOOL LLModalDialog::handleHover(S32 x, S32 y, MASK mask)
158{
159 if( childrenHandleHover(x, y, mask) == NULL )
160 {
161 getWindow()->setCursor(UI_CURSOR_ARROW);
162 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;
163 }
164 return TRUE;
165}
166
167BOOL LLModalDialog::handleMouseUp(S32 x, S32 y, MASK mask)
168{
169 childrenHandleMouseUp(x, y, mask);
170 return TRUE;
171}
172
173BOOL LLModalDialog::handleScrollWheel(S32 x, S32 y, S32 clicks)
174{
175 childrenHandleScrollWheel(x, y, clicks);
176 return TRUE;
177}
178
179BOOL LLModalDialog::handleDoubleClick(S32 x, S32 y, MASK mask)
180{
181 if (!LLFloater::handleDoubleClick(x, y, mask))
182 {
183 // Click outside the panel
184 make_ui_sound("UISndInvalidOp");
185 }
186 return TRUE;
187}
188
189BOOL LLModalDialog::handleRightMouseDown(S32 x, S32 y, MASK mask)
190{
191 childrenHandleRightMouseDown(x, y, mask);
192 return TRUE;
193}
194
195
196BOOL LLModalDialog::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent )
197{
198 childrenHandleKey(key, mask);
199
200 LLFloater::handleKeyHere(key, mask, called_from_parent );
201
202 if (mModal)
203 {
204 // Suck up all keystokes except CTRL-Q.
205 BOOL is_quit = ('Q' == key) && (MASK_CONTROL == mask);
206 return !is_quit;
207 }
208 else
209 {
210 // don't process escape key until message box has been on screen a minimal amount of time
211 // to avoid accidentally destroying the message box when user is hitting escape at the time it appears
212 BOOL enough_time_elapsed = mVisibleTime.getElapsedTimeF32() > 1.0f;
213 if (enough_time_elapsed && key == KEY_ESCAPE)
214 {
215 close();
216 return TRUE;
217 }
218 return FALSE;
219 }
220}
221
222void LLModalDialog::onClose(bool app_quitting)
223{
224 stopModal();
225 LLFloater::onClose(app_quitting);
226}
227
228// virtual
229void LLModalDialog::draw()
230{
231 if (getVisible())
232 {
233 LLColor4 shadow_color = LLUI::sColorsGroup->getColor("ColorDropShadow");
234 S32 shadow_lines = LLUI::sConfigGroup->getS32("DropShadowFloater");
235
236 gl_drop_shadow( 0, mRect.getHeight(), mRect.getWidth(), 0,
237 shadow_color, shadow_lines);
238
239 LLFloater::draw();
240
241 if (mModal)
242 {
243 // If we've lost focus to a non-child, get it back ASAP.
244 if( gFocusMgr.getTopView() != this )
245 {
246 gFocusMgr.setTopView( this, NULL);
247 }
248
249 if( !gFocusMgr.childHasKeyboardFocus( this ) )
250 {
251 setFocus(TRUE);
252 }
253
254 if( !gFocusMgr.childHasMouseCapture( this ) )
255 {
256 gFocusMgr.setMouseCapture( this, NULL );
257 }
258 }
259 }
260}
261
262void LLModalDialog::centerOnScreen()
263{
264 LLVector2 window_size = LLUI::getWindowSize();
265
266 S32 dialog_left = (llround(window_size.mV[VX]) - mRect.getWidth()) / 2;
267 S32 dialog_bottom = (llround(window_size.mV[VY]) - mRect.getHeight()) / 2;
268
269 translate( dialog_left - mRect.mLeft, dialog_bottom - mRect.mBottom );
270}
271
272
273// static
274void LLModalDialog::onAppFocusLost()
275{
276 if( !sModalStack.empty() )
277 {
278 LLModalDialog* instance = LLModalDialog::sModalStack.front();
279 if( gFocusMgr.childHasMouseCapture( instance ) )
280 {
281 gFocusMgr.setMouseCapture( NULL, NULL );
282 }
283
284 if( gFocusMgr.childHasKeyboardFocus( instance ) )
285 {
286 gFocusMgr.setKeyboardFocus( NULL, NULL );
287 }
288 }
289}
290
291// static
292void LLModalDialog::onAppFocusGained()
293{
294 if( !sModalStack.empty() )
295 {
296 LLModalDialog* instance = LLModalDialog::sModalStack.front();
297
298 // This is a modal dialog. It sucks up all mouse and keyboard operations.
299 gFocusMgr.setMouseCapture( instance, NULL );
300 instance->setFocus(TRUE);
301 gFocusMgr.setTopView( instance, NULL );
302
303 instance->centerOnScreen();
304 }
305}
306
307