00001 00032 #include "llviewerprecompiledheaders.h" 00033 00034 #include "lltoolmgr.h" 00035 00036 #include "lltool.h" 00037 // tools and manipulators 00038 #include "llmanipscale.h" 00039 #include "lltoolbrush.h" 00040 #include "lltoolcomp.h" 00041 #include "lltooldraganddrop.h" 00042 #include "lltoolface.h" 00043 #include "lltoolfocus.h" 00044 #include "lltoolgrab.h" 00045 #include "lltoolindividual.h" 00046 #include "lltoolmorph.h" 00047 #include "lltoolpie.h" 00048 #include "lltoolplacer.h" 00049 #include "lltoolselectland.h" 00050 #include "lltoolobjpicker.h" 00051 #include "lltoolpipette.h" 00052 #include "llagent.h" 00053 #include "llviewercontrol.h" 00054 00055 00056 // Used when app not active to avoid processing hover. 00057 LLTool* gToolNull = NULL; 00058 00059 LLToolset* gBasicToolset = NULL; 00060 LLToolset* gCameraToolset = NULL; 00061 //LLToolset* gLandToolset = NULL; 00062 LLToolset* gMouselookToolset = NULL; 00063 LLToolset* gFaceEditToolset = NULL; 00064 00066 // LLToolMgr 00067 00068 LLToolMgr::LLToolMgr() 00069 : 00070 mBaseTool(NULL), 00071 mSavedTool(NULL), 00072 mTransientTool( NULL ), 00073 mOverrideTool( NULL ), 00074 mSelectedTool( NULL ), 00075 mCurrentToolset( NULL ) 00076 { 00077 gToolNull = new LLTool(NULL); // Does nothing 00078 setCurrentTool(gToolNull); 00079 00080 gBasicToolset = new LLToolset(); 00081 gCameraToolset = new LLToolset(); 00082 // gLandToolset = new LLToolset(); 00083 gMouselookToolset = new LLToolset(); 00084 gFaceEditToolset = new LLToolset(); 00085 } 00086 00087 void LLToolMgr::initTools() 00088 { 00089 static BOOL initialized = FALSE; 00090 if(initialized) 00091 { 00092 return; 00093 } 00094 initialized = TRUE; 00095 gBasicToolset->addTool( LLToolPie::getInstance() ); 00096 gBasicToolset->addTool( LLToolCamera::getInstance() ); 00097 gCameraToolset->addTool( LLToolCamera::getInstance() ); 00098 gBasicToolset->addTool( LLToolGrab::getInstance() ); 00099 gBasicToolset->addTool( LLToolCompTranslate::getInstance() ); 00100 gBasicToolset->addTool( LLToolCompCreate::getInstance() ); 00101 gBasicToolset->addTool( LLToolBrushLand::getInstance() ); 00102 gMouselookToolset->addTool( LLToolCompGun::getInstance() ); 00103 gBasicToolset->addTool( LLToolCompInspect::getInstance() ); 00104 gFaceEditToolset->addTool( LLToolCamera::getInstance() ); 00105 00106 // On startup, use "select" tool 00107 setCurrentToolset(gBasicToolset); 00108 00109 gBasicToolset->selectTool( LLToolPie::getInstance() ); 00110 } 00111 00112 LLToolMgr::~LLToolMgr() 00113 { 00114 delete gBasicToolset; 00115 gBasicToolset = NULL; 00116 00117 delete gMouselookToolset; 00118 gMouselookToolset = NULL; 00119 00120 delete gFaceEditToolset; 00121 gFaceEditToolset = NULL; 00122 00123 delete gCameraToolset; 00124 gCameraToolset = NULL; 00125 00126 delete gToolNull; 00127 gToolNull = NULL; 00128 } 00129 00130 BOOL LLToolMgr::usingTransientTool() 00131 { 00132 return mTransientTool ? TRUE : FALSE; 00133 } 00134 00135 void LLToolMgr::setCurrentToolset(LLToolset* current) 00136 { 00137 if (!current) return; 00138 00139 // switching toolsets? 00140 if (current != mCurrentToolset) 00141 { 00142 // deselect current tool 00143 if (mSelectedTool) 00144 { 00145 mSelectedTool->handleDeselect(); 00146 } 00147 mCurrentToolset = current; 00148 // select first tool of new toolset only if toolset changed 00149 mCurrentToolset->selectFirstTool(); 00150 } 00151 // update current tool based on new toolset 00152 setCurrentTool( mCurrentToolset->getSelectedTool() ); 00153 } 00154 00155 LLToolset* LLToolMgr::getCurrentToolset() 00156 { 00157 return mCurrentToolset; 00158 } 00159 00160 void LLToolMgr::setCurrentTool( LLTool* tool ) 00161 { 00162 if (mTransientTool) 00163 { 00164 mTransientTool = NULL; 00165 } 00166 00167 mBaseTool = tool; 00168 updateToolStatus(); 00169 } 00170 00171 LLTool* LLToolMgr::getCurrentTool() 00172 { 00173 MASK override_mask = gKeyboard->currentMask(TRUE); 00174 00175 LLTool* cur_tool = NULL; 00176 // always use transient tools if available 00177 if (mTransientTool) 00178 { 00179 mOverrideTool = NULL; 00180 cur_tool = mTransientTool; 00181 } 00182 // tools currently grabbing mouse input will stay active 00183 else if (mSelectedTool && mSelectedTool->hasMouseCapture()) 00184 { 00185 cur_tool = mSelectedTool; 00186 } 00187 else 00188 { 00189 mOverrideTool = mBaseTool ? mBaseTool->getOverrideTool(override_mask) : NULL; 00190 00191 // use override tool if available otherwise drop back to base tool 00192 cur_tool = mOverrideTool ? mOverrideTool : mBaseTool; 00193 } 00194 00195 LLTool* prev_tool = mSelectedTool; 00196 // Set the selected tool to avoid infinite recursion 00197 mSelectedTool = cur_tool; 00198 00199 //update tool selection status 00200 if (prev_tool != cur_tool) 00201 { 00202 if (prev_tool) 00203 { 00204 prev_tool->handleDeselect(); 00205 } 00206 if (cur_tool) 00207 { 00208 cur_tool->handleSelect(); 00209 } 00210 } 00211 00212 return mSelectedTool; 00213 } 00214 00215 LLTool* LLToolMgr::getBaseTool() 00216 { 00217 return mBaseTool; 00218 } 00219 00220 void LLToolMgr::updateToolStatus() 00221 { 00222 // call getcurrenttool() to calculate active tool and call handleSelect() and handleDeselect() immediately 00223 // when active tool changes 00224 getCurrentTool(); 00225 } 00226 00227 BOOL LLToolMgr::inEdit() 00228 { 00229 return mBaseTool != LLToolPie::getInstance() && mBaseTool != gToolNull; 00230 } 00231 00232 bool LLToolMgr::inBuildMode() 00233 { 00234 // when entering mouselook inEdit() immediately returns true before 00235 // cameraMouselook() actually starts returning true. Also, appearance edit 00236 // sets build mode to true, so let's exclude that. 00237 bool b=(inEdit() 00238 && gSavedSettings.getBOOL("BuildBtnState") 00239 && !gAgent.cameraMouselook() 00240 && mCurrentToolset != gFaceEditToolset); 00241 00242 return b; 00243 } 00244 00245 void LLToolMgr::setTransientTool(LLTool* tool) 00246 { 00247 if (!tool) 00248 { 00249 clearTransientTool(); 00250 } 00251 else 00252 { 00253 if (mTransientTool) 00254 { 00255 mTransientTool = NULL; 00256 } 00257 00258 mTransientTool = tool; 00259 } 00260 00261 updateToolStatus(); 00262 } 00263 00264 void LLToolMgr::clearTransientTool() 00265 { 00266 if (mTransientTool) 00267 { 00268 mTransientTool = NULL; 00269 if (!mBaseTool) 00270 { 00271 llwarns << "mBaseTool is NULL" << llendl; 00272 } 00273 } 00274 updateToolStatus(); 00275 } 00276 00277 00278 // The "gun tool", used for handling mouselook, captures the mouse and 00279 // locks it within the window. When the app loses focus we need to 00280 // release this locking. 00281 void LLToolMgr::onAppFocusLost() 00282 { 00283 mSavedTool = mBaseTool; 00284 mBaseTool = gToolNull; 00285 updateToolStatus(); 00286 } 00287 00288 void LLToolMgr::onAppFocusGained() 00289 { 00290 if (mSavedTool) 00291 { 00292 mBaseTool = mSavedTool; 00293 mSavedTool = NULL; 00294 } 00295 updateToolStatus(); 00296 } 00297 00298 void LLToolMgr::clearSavedTool() 00299 { 00300 mSavedTool = NULL; 00301 } 00302 00304 // LLToolset 00305 00306 void LLToolset::addTool(LLTool* tool) 00307 { 00308 mToolList.push_back( tool ); 00309 if( !mSelectedTool ) 00310 { 00311 mSelectedTool = tool; 00312 } 00313 } 00314 00315 00316 void LLToolset::selectTool(LLTool* tool) 00317 { 00318 mSelectedTool = tool; 00319 LLToolMgr::getInstance()->setCurrentTool( mSelectedTool ); 00320 } 00321 00322 00323 void LLToolset::selectToolByIndex( S32 index ) 00324 { 00325 LLTool *tool = (index >= 0 && index < (S32)mToolList.size()) ? mToolList[index] : NULL; 00326 if (tool) 00327 { 00328 mSelectedTool = tool; 00329 LLToolMgr::getInstance()->setCurrentTool( tool ); 00330 } 00331 } 00332 00333 BOOL LLToolset::isToolSelected( S32 index ) 00334 { 00335 LLTool *tool = (index >= 0 && index < (S32)mToolList.size()) ? mToolList[index] : NULL; 00336 return (tool == mSelectedTool); 00337 } 00338 00339 00340 void LLToolset::selectFirstTool() 00341 { 00342 mSelectedTool = (0 < mToolList.size()) ? mToolList[0] : NULL; 00343 LLToolMgr::getInstance()->setCurrentTool( mSelectedTool ); 00344 } 00345 00346 00347 void LLToolset::selectNextTool() 00348 { 00349 LLTool* next = NULL; 00350 for( tool_list_t::iterator iter = mToolList.begin(); 00351 iter != mToolList.end(); ) 00352 { 00353 LLTool* cur = *iter++; 00354 if( cur == mSelectedTool && iter != mToolList.end() ) 00355 { 00356 next = *iter; 00357 break; 00358 } 00359 } 00360 00361 if( next ) 00362 { 00363 mSelectedTool = next; 00364 LLToolMgr::getInstance()->setCurrentTool( mSelectedTool ); 00365 } 00366 else 00367 { 00368 selectFirstTool(); 00369 } 00370 } 00371 00372 void LLToolset::selectPrevTool() 00373 { 00374 LLTool* prev = NULL; 00375 for( tool_list_t::reverse_iterator iter = mToolList.rbegin(); 00376 iter != mToolList.rend(); ) 00377 { 00378 LLTool* cur = *iter++; 00379 if( cur == mSelectedTool && iter != mToolList.rend() ) 00380 { 00381 prev = *iter; 00382 break; 00383 } 00384 } 00385 00386 if( prev ) 00387 { 00388 mSelectedTool = prev; 00389 LLToolMgr::getInstance()->setCurrentTool( mSelectedTool ); 00390 } 00391 else if (mToolList.size() > 0) 00392 { 00393 selectToolByIndex((S32)mToolList.size()-1); 00394 } 00395 } 00396 00397 void select_tool( void *tool_pointer ) 00398 { 00399 LLTool *tool = (LLTool *)tool_pointer; 00400 LLToolMgr::getInstance()->getCurrentToolset()->selectTool( tool ); 00401 }