00001
00032 #include "linden_common.h"
00033
00034 #include "llmodaldialog.h"
00035
00036 #include "llfocusmgr.h"
00037 #include "v4color.h"
00038 #include "v2math.h"
00039 #include "llui.h"
00040 #include "llwindow.h"
00041 #include "llkeyboard.h"
00042
00043
00044 std::list<LLModalDialog*> LLModalDialog::sModalStack;
00045
00046 LLModalDialog::LLModalDialog( const LLString& title, S32 width, S32 height, BOOL modal )
00047 : LLFloater( "modal container",
00048 LLRect( 0, height, width, 0 ),
00049 title,
00050 FALSE,
00051 DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT,
00052 FALSE,
00053 modal ? FALSE : TRUE,
00054 modal ? FALSE : TRUE,
00055 TRUE),
00056 mModal( modal )
00057 {
00058 setVisible( FALSE );
00059 setBackgroundVisible(TRUE);
00060 setBackgroundOpaque(TRUE);
00061 centerOnScreen();
00062 }
00063
00064 LLModalDialog::~LLModalDialog()
00065 {
00066
00067 if (gFocusMgr.childHasKeyboardFocus(this))
00068 {
00069 gFocusMgr.unlockFocus();
00070 }
00071 }
00072
00073 void LLModalDialog::reshape(S32 width, S32 height, BOOL called_from_parent)
00074 {
00075 LLFloater::reshape(width, height, called_from_parent);
00076 centerOnScreen();
00077 }
00078
00079 void LLModalDialog::startModal()
00080 {
00081 if (mModal)
00082 {
00083
00084 if (!sModalStack.empty())
00085 {
00086 LLModalDialog* front = sModalStack.front();
00087 front->setVisible(FALSE);
00088 }
00089
00090
00091 gFocusMgr.setMouseCapture( this );
00092 gFocusMgr.setTopCtrl( this );
00093 setFocus(TRUE);
00094
00095 sModalStack.push_front( this );
00096 }
00097
00098 setVisible( TRUE );
00099 }
00100
00101 void LLModalDialog::stopModal()
00102 {
00103 gFocusMgr.unlockFocus();
00104 gFocusMgr.releaseFocusIfNeeded( this );
00105
00106 if (mModal)
00107 {
00108 std::list<LLModalDialog*>::iterator iter = std::find(sModalStack.begin(), sModalStack.end(), this);
00109 if (iter != sModalStack.end())
00110 {
00111 sModalStack.erase(iter);
00112 }
00113 else
00114 {
00115 llwarns << "LLModalDialog::stopModal not in list!" << llendl;
00116 }
00117 }
00118 if (!sModalStack.empty())
00119 {
00120 LLModalDialog* front = sModalStack.front();
00121 front->setVisible(TRUE);
00122 }
00123 }
00124
00125
00126 void LLModalDialog::setVisible( BOOL visible )
00127 {
00128 if (mModal)
00129 {
00130 if( visible )
00131 {
00132
00133 gFocusMgr.setMouseCapture( this );
00134
00135
00136 gFocusMgr.setTopCtrl( this );
00137 setFocus( TRUE );
00138 }
00139 else
00140 {
00141 gFocusMgr.releaseFocusIfNeeded( this );
00142 }
00143 }
00144
00145 LLFloater::setVisible( visible );
00146 }
00147
00148 BOOL LLModalDialog::handleMouseDown(S32 x, S32 y, MASK mask)
00149 {
00150 if (!LLFloater::handleMouseDown(x, y, mask))
00151 {
00152 if (mModal)
00153 {
00154
00155 make_ui_sound("UISndInvalidOp");
00156 }
00157 }
00158 return TRUE;
00159 }
00160
00161 BOOL LLModalDialog::handleHover(S32 x, S32 y, MASK mask)
00162 {
00163 if( childrenHandleHover(x, y, mask) == NULL )
00164 {
00165 getWindow()->setCursor(UI_CURSOR_ARROW);
00166 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;
00167 }
00168 return TRUE;
00169 }
00170
00171 BOOL LLModalDialog::handleMouseUp(S32 x, S32 y, MASK mask)
00172 {
00173 childrenHandleMouseUp(x, y, mask);
00174 return TRUE;
00175 }
00176
00177 BOOL LLModalDialog::handleScrollWheel(S32 x, S32 y, S32 clicks)
00178 {
00179 childrenHandleScrollWheel(x, y, clicks);
00180 return TRUE;
00181 }
00182
00183 BOOL LLModalDialog::handleDoubleClick(S32 x, S32 y, MASK mask)
00184 {
00185 if (!LLFloater::handleDoubleClick(x, y, mask))
00186 {
00187
00188 make_ui_sound("UISndInvalidOp");
00189 }
00190 return TRUE;
00191 }
00192
00193 BOOL LLModalDialog::handleRightMouseDown(S32 x, S32 y, MASK mask)
00194 {
00195 childrenHandleRightMouseDown(x, y, mask);
00196 return TRUE;
00197 }
00198
00199
00200 BOOL LLModalDialog::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent )
00201 {
00202 childrenHandleKey(key, mask);
00203
00204 LLFloater::handleKeyHere(key, mask, called_from_parent );
00205
00206 if (mModal)
00207 {
00208
00209 BOOL is_quit = ('Q' == key) && (MASK_CONTROL == mask);
00210 return !is_quit;
00211 }
00212 else
00213 {
00214
00215
00216 BOOL enough_time_elapsed = mVisibleTime.getElapsedTimeF32() > 1.0f;
00217 if (enough_time_elapsed && key == KEY_ESCAPE)
00218 {
00219 close();
00220 return TRUE;
00221 }
00222 return FALSE;
00223 }
00224 }
00225
00226 void LLModalDialog::onClose(bool app_quitting)
00227 {
00228 stopModal();
00229 LLFloater::onClose(app_quitting);
00230 }
00231
00232
00233 void LLModalDialog::draw()
00234 {
00235 if (getVisible())
00236 {
00237 LLColor4 shadow_color = LLUI::sColorsGroup->getColor("ColorDropShadow");
00238 S32 shadow_lines = LLUI::sConfigGroup->getS32("DropShadowFloater");
00239
00240 gl_drop_shadow( 0, mRect.getHeight(), mRect.getWidth(), 0,
00241 shadow_color, shadow_lines);
00242
00243 LLFloater::draw();
00244
00245 if (mModal)
00246 {
00247
00248 if( gFocusMgr.getTopCtrl() != this )
00249 {
00250 gFocusMgr.setTopCtrl( this );
00251 }
00252
00253 if( !gFocusMgr.childHasKeyboardFocus( this ) )
00254 {
00255 setFocus(TRUE);
00256 }
00257
00258 if( !gFocusMgr.childHasMouseCapture( this ) )
00259 {
00260 gFocusMgr.setMouseCapture( this );
00261 }
00262 }
00263 }
00264 }
00265
00266 void LLModalDialog::centerOnScreen()
00267 {
00268 LLVector2 window_size = LLUI::getWindowSize();
00269
00270 S32 dialog_left = (llround(window_size.mV[VX]) - mRect.getWidth()) / 2;
00271 S32 dialog_bottom = (llround(window_size.mV[VY]) - mRect.getHeight()) / 2;
00272
00273 translate( dialog_left - mRect.mLeft, dialog_bottom - mRect.mBottom );
00274 }
00275
00276
00277
00278 void LLModalDialog::onAppFocusLost()
00279 {
00280 if( !sModalStack.empty() )
00281 {
00282 LLModalDialog* instance = LLModalDialog::sModalStack.front();
00283 if( gFocusMgr.childHasMouseCapture( instance ) )
00284 {
00285 gFocusMgr.setMouseCapture( NULL );
00286 }
00287
00288 if( gFocusMgr.childHasKeyboardFocus( instance ) )
00289 {
00290 gFocusMgr.setKeyboardFocus( NULL, NULL );
00291 }
00292 }
00293 }
00294
00295
00296 void LLModalDialog::onAppFocusGained()
00297 {
00298 if( !sModalStack.empty() )
00299 {
00300 LLModalDialog* instance = LLModalDialog::sModalStack.front();
00301
00302
00303 gFocusMgr.setMouseCapture( instance );
00304 instance->setFocus(TRUE);
00305 gFocusMgr.setTopCtrl( instance );
00306
00307 instance->centerOnScreen();
00308 }
00309 }
00310
00311