llmodaldialog.cpp

Go to the documentation of this file.
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 // static
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, // resizable
00051                                  DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT,
00052                                  FALSE, // drag_on_left
00053                                  modal ? FALSE : TRUE, // minimizable
00054                                  modal ? FALSE : TRUE, // close button
00055                                  TRUE), // bordered
00056           mModal( modal )
00057 {
00058         setVisible( FALSE );
00059         setBackgroundVisible(TRUE);
00060         setBackgroundOpaque(TRUE);
00061         centerOnScreen(); // default position
00062 }
00063 
00064 LLModalDialog::~LLModalDialog()
00065 {
00066         // don't unlock focus unless we have it
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                 // If Modal, Hide the active modal dialog
00084                 if (!sModalStack.empty())
00085                 {
00086                         LLModalDialog* front = sModalStack.front();
00087                         front->setVisible(FALSE);
00088                 }
00089         
00090                 // This is a modal dialog.  It sucks up all mouse and keyboard operations.
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                         // This is a modal dialog.  It sucks up all mouse and keyboard operations.
00133                         gFocusMgr.setMouseCapture( this );
00134 
00135                         // The dialog view is a root view
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                         // Click was outside the panel
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                 // Click outside the panel
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                 // Suck up all keystokes except CTRL-Q.
00209                 BOOL is_quit = ('Q' == key) && (MASK_CONTROL == mask);
00210                 return !is_quit;
00211         }
00212         else
00213         {
00214                 // don't process escape key until message box has been on screen a minimal amount of time
00215                 // to avoid accidentally destroying the message box when user is hitting escape at the time it appears
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 // virtual
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                         // If we've lost focus to a non-child, get it back ASAP.
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 // static 
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 // static 
00296 void LLModalDialog::onAppFocusGained()
00297 {
00298         if( !sModalStack.empty() )
00299         {
00300                 LLModalDialog* instance = LLModalDialog::sModalStack.front();
00301 
00302                 // This is a modal dialog.  It sucks up all mouse and keyboard operations.
00303                 gFocusMgr.setMouseCapture( instance );
00304                 instance->setFocus(TRUE);
00305                 gFocusMgr.setTopCtrl( instance );
00306 
00307                 instance->centerOnScreen();
00308         }
00309 }
00310 
00311 

Generated on Thu Jul 1 06:08:54 2010 for Second Life Viewer by  doxygen 1.4.7