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 // virtual
00074 void LLModalDialog::open()      /* Flawfinder: ignore */
00075 {
00076         // SJB: Hack! Make sure we don't ever host a modal dialog
00077         LLMultiFloater* thost = LLFloater::getFloaterHost();
00078         LLFloater::setFloaterHost(NULL);
00079         LLFloater::open();
00080         LLFloater::setFloaterHost(thost);
00081 }
00082 
00083 void LLModalDialog::reshape(S32 width, S32 height, BOOL called_from_parent)
00084 {
00085         LLFloater::reshape(width, height, called_from_parent);
00086         centerOnScreen();
00087 }
00088 
00089 void LLModalDialog::startModal()
00090 {
00091         if (mModal)
00092         {
00093                 // If Modal, Hide the active modal dialog
00094                 if (!sModalStack.empty())
00095                 {
00096                         LLModalDialog* front = sModalStack.front();
00097                         front->setVisible(FALSE);
00098                 }
00099         
00100                 // This is a modal dialog.  It sucks up all mouse and keyboard operations.
00101                 gFocusMgr.setMouseCapture( this );
00102                 gFocusMgr.setTopCtrl( this );
00103                 setFocus(TRUE);
00104 
00105                 sModalStack.push_front( this );
00106         }
00107 
00108         setVisible( TRUE );
00109 }
00110 
00111 void LLModalDialog::stopModal()
00112 {
00113         gFocusMgr.unlockFocus();
00114         gFocusMgr.releaseFocusIfNeeded( this );
00115 
00116         if (mModal)
00117         {
00118                 std::list<LLModalDialog*>::iterator iter = std::find(sModalStack.begin(), sModalStack.end(), this);
00119                 if (iter != sModalStack.end())
00120                 {
00121                         sModalStack.erase(iter);
00122                 }
00123                 else
00124                 {
00125                         llwarns << "LLModalDialog::stopModal not in list!" << llendl;
00126                 }
00127         }
00128         if (!sModalStack.empty())
00129         {
00130                 LLModalDialog* front = sModalStack.front();
00131                 front->setVisible(TRUE);
00132         }
00133 }
00134 
00135 
00136 void LLModalDialog::setVisible( BOOL visible )
00137 {
00138         if (mModal)
00139         {
00140                 if( visible )
00141                 {
00142                         // This is a modal dialog.  It sucks up all mouse and keyboard operations.
00143                         gFocusMgr.setMouseCapture( this );
00144 
00145                         // The dialog view is a root view
00146                         gFocusMgr.setTopCtrl( this );
00147                         setFocus( TRUE );
00148                 }
00149                 else
00150                 {
00151                         gFocusMgr.releaseFocusIfNeeded( this );
00152                 }
00153         }
00154         
00155         LLFloater::setVisible( visible );
00156 }
00157 
00158 BOOL LLModalDialog::handleMouseDown(S32 x, S32 y, MASK mask)
00159 {
00160         if (mModal)
00161         {
00162                 if (!LLFloater::handleMouseDown(x, y, mask))
00163                 {
00164                         // Click was outside the panel
00165                         make_ui_sound("UISndInvalidOp");
00166                 }
00167         }
00168         else
00169         {
00170                 LLFloater::handleMouseDown(x, y, mask);
00171         }
00172         return TRUE;
00173 }
00174 
00175 BOOL LLModalDialog::handleHover(S32 x, S32 y, MASK mask)                
00176 { 
00177         if( childrenHandleHover(x, y, mask) == NULL )
00178         {
00179                 getWindow()->setCursor(UI_CURSOR_ARROW);
00180                 lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;              
00181         }
00182         return TRUE;
00183 }
00184 
00185 BOOL LLModalDialog::handleMouseUp(S32 x, S32 y, MASK mask)
00186 {
00187         childrenHandleMouseUp(x, y, mask);
00188         return TRUE;
00189 }
00190 
00191 BOOL LLModalDialog::handleScrollWheel(S32 x, S32 y, S32 clicks)
00192 {
00193         childrenHandleScrollWheel(x, y, clicks);
00194         return TRUE;
00195 }
00196 
00197 BOOL LLModalDialog::handleDoubleClick(S32 x, S32 y, MASK mask)
00198 {
00199         if (!LLFloater::handleDoubleClick(x, y, mask))
00200         {
00201                 // Click outside the panel
00202                 make_ui_sound("UISndInvalidOp");
00203         }
00204         return TRUE;
00205 }
00206 
00207 BOOL LLModalDialog::handleRightMouseDown(S32 x, S32 y, MASK mask)
00208 {
00209         childrenHandleRightMouseDown(x, y, mask);
00210         return TRUE;
00211 }
00212 
00213 
00214 BOOL LLModalDialog::handleKeyHere(KEY key, MASK mask )
00215 {
00216         LLFloater::handleKeyHere(key, mask );
00217 
00218         if (mModal)
00219         {
00220                 // Suck up all keystokes except CTRL-Q.
00221                 BOOL is_quit = ('Q' == key) && (MASK_CONTROL == mask);
00222                 return !is_quit;
00223         }
00224         else
00225         {
00226                 // don't process escape key until message box has been on screen a minimal amount of time
00227                 // to avoid accidentally destroying the message box when user is hitting escape at the time it appears
00228                 BOOL enough_time_elapsed = mVisibleTime.getElapsedTimeF32() > 1.0f;
00229                 if (enough_time_elapsed && key == KEY_ESCAPE)
00230                 {
00231                         close();
00232                         return TRUE;
00233                 }
00234                 return FALSE;
00235         }       
00236 }
00237 
00238 void LLModalDialog::onClose(bool app_quitting)
00239 {
00240         stopModal();
00241         LLFloater::onClose(app_quitting);
00242 }
00243 
00244 // virtual
00245 void LLModalDialog::draw()
00246 {
00247         LLColor4 shadow_color = LLUI::sColorsGroup->getColor("ColorDropShadow");
00248         S32 shadow_lines = LLUI::sConfigGroup->getS32("DropShadowFloater");
00249 
00250         gl_drop_shadow( 0, getRect().getHeight(), getRect().getWidth(), 0,
00251                 shadow_color, shadow_lines);
00252 
00253         LLFloater::draw();
00254 
00255         if (mModal)
00256         {
00257                 // If we've lost focus to a non-child, get it back ASAP.
00258                 if( gFocusMgr.getTopCtrl() != this )
00259                 {
00260                         gFocusMgr.setTopCtrl( this );
00261                 }
00262 
00263                 if( !gFocusMgr.childHasKeyboardFocus( this ) )
00264                 {
00265                         setFocus(TRUE);
00266                 }
00267 
00268                 if( !gFocusMgr.childHasMouseCapture( this ) )
00269                 {
00270                         gFocusMgr.setMouseCapture( this );
00271                 }
00272         }
00273 }
00274 
00275 void LLModalDialog::centerOnScreen()
00276 {
00277         LLVector2 window_size = LLUI::getWindowSize();
00278         centerWithin(LLRect(0, 0, llround(window_size.mV[VX]), llround(window_size.mV[VY])));
00279 }
00280 
00281 
00282 // static 
00283 void LLModalDialog::onAppFocusLost()
00284 {
00285         if( !sModalStack.empty() )
00286         {
00287                 LLModalDialog* instance = LLModalDialog::sModalStack.front();
00288                 if( gFocusMgr.childHasMouseCapture( instance ) )
00289                 {
00290                         gFocusMgr.setMouseCapture( NULL );
00291                 }
00292 
00293                 if( gFocusMgr.childHasKeyboardFocus( instance ) )
00294                 {
00295                         gFocusMgr.setKeyboardFocus( NULL );
00296                 }
00297         }
00298 }
00299 
00300 // static 
00301 void LLModalDialog::onAppFocusGained()
00302 {
00303         if( !sModalStack.empty() )
00304         {
00305                 LLModalDialog* instance = LLModalDialog::sModalStack.front();
00306 
00307                 // This is a modal dialog.  It sucks up all mouse and keyboard operations.
00308                 gFocusMgr.setMouseCapture( instance );
00309                 instance->setFocus(TRUE);
00310                 gFocusMgr.setTopCtrl( instance );
00311 
00312                 instance->centerOnScreen();
00313         }
00314 }
00315 
00316 
00317 

Generated on Fri May 16 08:32:54 2008 for SecondLife by  doxygen 1.5.5