00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "lltoolcomp.h"
00035
00036 #include "llgl.h"
00037 #include "indra_constants.h"
00038
00039 #include "llmanip.h"
00040 #include "llmaniprotate.h"
00041 #include "llmanipscale.h"
00042 #include "llmaniptranslate.h"
00043 #include "llmenugl.h"
00044 #include "llselectmgr.h"
00045 #include "lltoolfocus.h"
00046 #include "lltoolgrab.h"
00047 #include "lltoolgun.h"
00048 #include "lltoolmgr.h"
00049 #include "lltoolselect.h"
00050 #include "lltoolselectrect.h"
00051 #include "lltoolplacer.h"
00052 #include "llviewermenu.h"
00053 #include "llviewerobject.h"
00054 #include "llviewerwindow.h"
00055 #include "llagent.h"
00056 #include "llfloatertools.h"
00057 #include "llviewercontrol.h"
00058
00059 const S32 BUTTON_HEIGHT = 16;
00060 const S32 BUTTON_WIDTH_SMALL = 32;
00061 const S32 BUTTON_WIDTH_BIG = 48;
00062 const S32 HPAD = 4;
00063
00064
00065 LLToolCompInspect *gToolInspect = NULL;
00066 LLToolCompTranslate *gToolTranslate = NULL;
00067 LLToolCompScale *gToolStretch = NULL;
00068 LLToolCompRotate *gToolRotate = NULL;
00069 LLToolCompCreate *gToolCreate = NULL;
00070 LLToolCompGun *gToolGun = NULL;
00071
00072 extern LLControlGroup gSavedSettings;
00073
00074
00075
00076
00077
00078
00079 void LLToolComposite::setCurrentTool( LLTool* new_tool )
00080 {
00081 if( mCur != new_tool )
00082 {
00083 if( mSelected )
00084 {
00085 mCur->handleDeselect();
00086 mCur = new_tool;
00087 mCur->handleSelect();
00088 }
00089 else
00090 {
00091 mCur = new_tool;
00092 }
00093 }
00094 }
00095
00096 LLToolComposite::LLToolComposite(const LLString& name)
00097 : LLTool(name),
00098 mCur(NULL), mDefault(NULL), mSelected(FALSE),
00099 mMouseDown(FALSE), mManip(NULL), mSelectRect(NULL)
00100 {
00101 }
00102
00103
00104 BOOL LLToolComposite::handleMouseUp(S32 x, S32 y, MASK mask)
00105 {
00106 BOOL handled = mCur->handleMouseUp( x, y, mask );
00107 if( handled )
00108 {
00109 setCurrentTool( mDefault );
00110 }
00111 return handled;
00112 }
00113
00114 void LLToolComposite::onMouseCaptureLost()
00115 {
00116 mCur->onMouseCaptureLost();
00117 setCurrentTool( mDefault );
00118 }
00119
00120 BOOL LLToolComposite::isSelecting()
00121 {
00122 return mCur == mSelectRect;
00123 }
00124
00125 void LLToolComposite::handleSelect()
00126 {
00127 if (!gSavedSettings.getBOOL("EditLinkedParts"))
00128 {
00129 gSelectMgr->promoteSelectionToRoot();
00130 }
00131 mCur = mDefault;
00132 mCur->handleSelect();
00133 mSelected = TRUE;
00134 }
00135
00136
00137
00138
00139
00140 LLToolCompInspect::LLToolCompInspect()
00141 : LLToolComposite("Inspect")
00142 {
00143 mSelectRect = new LLToolSelectRect(this);
00144 mDefault = mSelectRect;
00145 }
00146
00147
00148 LLToolCompInspect::~LLToolCompInspect()
00149 {
00150 delete mSelectRect;
00151 mSelectRect = NULL;
00152 }
00153
00154 BOOL LLToolCompInspect::handleMouseDown(S32 x, S32 y, MASK mask)
00155 {
00156 mMouseDown = TRUE;
00157 gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback);
00158 return TRUE;
00159 }
00160
00161 void LLToolCompInspect::pickCallback(S32 x, S32 y, MASK mask)
00162 {
00163 LLViewerObject* hit_obj = gViewerWindow->lastObjectHit();
00164
00165 if (!gToolInspect->mMouseDown)
00166 {
00167
00168 gToolInspect->mSelectRect->handleObjectSelection(hit_obj, mask, gSavedSettings.getBOOL("EditLinkedParts"), FALSE);
00169 return;
00170 }
00171
00172 if( hit_obj )
00173 {
00174 if (gSelectMgr->getSelection()->getObjectCount())
00175 {
00176 gEditMenuHandler = gSelectMgr;
00177 }
00178 gToolInspect->setCurrentTool( gToolInspect->mSelectRect );
00179 gToolInspect->mSelectRect->handleMouseDown( x, y, mask );
00180
00181 }
00182 else
00183 {
00184 gToolInspect->setCurrentTool( gToolInspect->mSelectRect );
00185 gToolInspect->mSelectRect->handleMouseDown( x, y, mask);
00186 }
00187 }
00188
00189 BOOL LLToolCompInspect::handleDoubleClick(S32 x, S32 y, MASK mask)
00190 {
00191 return TRUE;
00192 }
00193
00194
00195
00196
00197
00198 LLToolCompTranslate::LLToolCompTranslate()
00199 : LLToolComposite("Move")
00200 {
00201 mManip = new LLManipTranslate(this);
00202 mSelectRect = new LLToolSelectRect(this);
00203
00204 mCur = mManip;
00205 mDefault = mManip;
00206 }
00207
00208 LLToolCompTranslate::~LLToolCompTranslate()
00209 {
00210 delete mManip;
00211 mManip = NULL;
00212
00213 delete mSelectRect;
00214 mSelectRect = NULL;
00215 }
00216
00217 BOOL LLToolCompTranslate::handleHover(S32 x, S32 y, MASK mask)
00218 {
00219 if( !mCur->hasMouseCapture() )
00220 {
00221 setCurrentTool( mManip );
00222 }
00223 return mCur->handleHover( x, y, mask );
00224 }
00225
00226
00227 BOOL LLToolCompTranslate::handleMouseDown(S32 x, S32 y, MASK mask)
00228 {
00229 mMouseDown = TRUE;
00230 gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback, TRUE);
00231 return TRUE;
00232 }
00233
00234 void LLToolCompTranslate::pickCallback(S32 x, S32 y, MASK mask)
00235 {
00236 LLViewerObject* hit_obj = gViewerWindow->lastObjectHit();
00237
00238 gToolTranslate->mManip->highlightManipulators(x, y);
00239 if (!gToolTranslate->mMouseDown)
00240 {
00241
00242 gToolTranslate->mSelectRect->handleObjectSelection(hit_obj, mask, gSavedSettings.getBOOL("EditLinkedParts"), FALSE);
00243 return;
00244 }
00245
00246 if( hit_obj || gToolTranslate->mManip->getHighlightedPart() != LLManip::LL_NO_PART )
00247 {
00248 if (gToolTranslate->mManip->getSelection()->getObjectCount())
00249 {
00250 gEditMenuHandler = gSelectMgr;
00251 }
00252
00253 BOOL can_move = gToolTranslate->mManip->canAffectSelection();
00254
00255 if( LLManip::LL_NO_PART != gToolTranslate->mManip->getHighlightedPart() && can_move)
00256 {
00257 gToolTranslate->setCurrentTool( gToolTranslate->mManip );
00258 gToolTranslate->mManip->handleMouseDownOnPart( x, y, mask );
00259 }
00260 else
00261 {
00262 gToolTranslate->setCurrentTool( gToolTranslate->mSelectRect );
00263 gToolTranslate->mSelectRect->handleMouseDown( x, y, mask );
00264
00265
00266
00267 }
00268 }
00269 else
00270 {
00271 gToolTranslate->setCurrentTool( gToolTranslate->mSelectRect );
00272 gToolTranslate->mSelectRect->handleMouseDown( x, y, mask);
00273 }
00274 }
00275
00276 BOOL LLToolCompTranslate::handleMouseUp(S32 x, S32 y, MASK mask)
00277 {
00278 mMouseDown = FALSE;
00279 return LLToolComposite::handleMouseUp(x, y, mask);
00280 }
00281
00282 LLTool* LLToolCompTranslate::getOverrideTool(MASK mask)
00283 {
00284 if (mask == MASK_CONTROL)
00285 {
00286 return gToolRotate;
00287 }
00288 else if (mask == (MASK_CONTROL | MASK_SHIFT))
00289 {
00290 return gToolStretch;
00291 }
00292 return LLToolComposite::getOverrideTool(mask);
00293 }
00294
00295 BOOL LLToolCompTranslate::handleDoubleClick(S32 x, S32 y, MASK mask)
00296 {
00297 if (mManip->getSelection()->isEmpty() && mManip->getHighlightedPart() == LLManip::LL_NO_PART)
00298 {
00299
00300
00301 gFloaterTools->showPanel(LLFloaterTools::PANEL_CONTENTS);
00302 return TRUE;
00303 }
00304
00305
00306 return FALSE;
00307 }
00308
00309
00310 void LLToolCompTranslate::render()
00311 {
00312 mCur->render();
00313
00314 if( mCur != mManip )
00315 {
00316 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
00317 mManip->renderGuidelines();
00318 }
00319 }
00320
00321
00322
00323
00324
00325 LLToolCompScale::LLToolCompScale()
00326 : LLToolComposite("Stretch")
00327 {
00328 mManip = new LLManipScale(this);
00329 mSelectRect = new LLToolSelectRect(this);
00330
00331 mCur = mManip;
00332 mDefault = mManip;
00333 }
00334
00335 LLToolCompScale::~LLToolCompScale()
00336 {
00337 delete mManip;
00338 delete mSelectRect;
00339 }
00340
00341 BOOL LLToolCompScale::handleHover(S32 x, S32 y, MASK mask)
00342 {
00343 if( !mCur->hasMouseCapture() )
00344 {
00345 setCurrentTool(mManip );
00346 }
00347 return mCur->handleHover( x, y, mask );
00348 }
00349
00350
00351 BOOL LLToolCompScale::handleMouseDown(S32 x, S32 y, MASK mask)
00352 {
00353 mMouseDown = TRUE;
00354 gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback);
00355 return TRUE;
00356 }
00357
00358 void LLToolCompScale::pickCallback(S32 x, S32 y, MASK mask)
00359 {
00360 LLViewerObject* hit_obj = gViewerWindow->lastObjectHit();
00361
00362 gToolStretch->mManip->highlightManipulators(x, y);
00363 if (!gToolStretch->mMouseDown)
00364 {
00365
00366 gToolStretch->mSelectRect->handleObjectSelection(hit_obj, mask, gSavedSettings.getBOOL("EditLinkedParts"), FALSE);
00367
00368 return;
00369 }
00370
00371 if( hit_obj || gToolStretch->mManip->getHighlightedPart() != LLManip::LL_NO_PART)
00372 {
00373 if (gToolStretch->mManip->getSelection()->getObjectCount())
00374 {
00375 gEditMenuHandler = gSelectMgr;
00376 }
00377 if( LLManip::LL_NO_PART != gToolStretch->mManip->getHighlightedPart() )
00378 {
00379 gToolStretch->setCurrentTool( gToolStretch->mManip );
00380 gToolStretch->mManip->handleMouseDownOnPart( x, y, mask );
00381 }
00382 else
00383 {
00384 gToolStretch->setCurrentTool( gToolStretch->mSelectRect );
00385 gToolStretch->mSelectRect->handleMouseDown( x, y, mask );
00386 }
00387 }
00388 else
00389 {
00390 gToolStretch->setCurrentTool( gToolStretch->mSelectRect );
00391 gToolStretch->mCur->handleMouseDown( x, y, mask );
00392 }
00393 }
00394
00395 BOOL LLToolCompScale::handleMouseUp(S32 x, S32 y, MASK mask)
00396 {
00397 mMouseDown = FALSE;
00398 return LLToolComposite::handleMouseUp(x, y, mask);
00399 }
00400
00401 LLTool* LLToolCompScale::getOverrideTool(MASK mask)
00402 {
00403 if (mask == MASK_CONTROL)
00404 {
00405 return gToolRotate;
00406 }
00407
00408 return LLToolComposite::getOverrideTool(mask);
00409 }
00410
00411
00412 BOOL LLToolCompScale::handleDoubleClick(S32 x, S32 y, MASK mask)
00413 {
00414 if (!mManip->getSelection()->isEmpty() && mManip->getHighlightedPart() == LLManip::LL_NO_PART)
00415 {
00416
00417
00418 gFloaterTools->showPanel(LLFloaterTools::PANEL_CONTENTS);
00419
00420 return TRUE;
00421 }
00422 else
00423 {
00424
00425
00426 return handleMouseDown(x, y, mask);
00427 }
00428 }
00429
00430
00431 void LLToolCompScale::render()
00432 {
00433 mCur->render();
00434
00435 if( mCur != mManip )
00436 {
00437 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
00438 mManip->renderGuidelines();
00439 }
00440 }
00441
00442
00443
00444
00445 LLToolCompCreate::LLToolCompCreate()
00446 : LLToolComposite("Create")
00447 {
00448 mPlacer = new LLToolPlacer();
00449 mSelectRect = new LLToolSelectRect(this);
00450
00451 mCur = mPlacer;
00452 mDefault = mPlacer;
00453 mObjectPlacedOnMouseDown = FALSE;
00454 }
00455
00456
00457 LLToolCompCreate::~LLToolCompCreate()
00458 {
00459 delete mPlacer;
00460 delete mSelectRect;
00461 }
00462
00463
00464 BOOL LLToolCompCreate::handleMouseDown(S32 x, S32 y, MASK mask)
00465 {
00466 BOOL handled = FALSE;
00467 mMouseDown = TRUE;
00468
00469 if ( !(mask == MASK_SHIFT) && !(mask == MASK_CONTROL) )
00470 {
00471 setCurrentTool( mPlacer );
00472 handled = mPlacer->placeObject( x, y, mask );
00473 }
00474 else
00475 {
00476 gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback);
00477 handled = TRUE;
00478 }
00479
00480 mObjectPlacedOnMouseDown = TRUE;
00481
00482 return TRUE;
00483 }
00484
00485 void LLToolCompCreate::pickCallback(S32 x, S32 y, MASK mask)
00486 {
00487
00488
00489 mask = (mask & ~MASK_SHIFT);
00490 mask = (mask & ~MASK_CONTROL);
00491
00492 gToolCreate->setCurrentTool( gToolCreate->mSelectRect );
00493 gToolCreate->mSelectRect->handleMouseDown( x, y, mask);
00494 }
00495
00496 BOOL LLToolCompCreate::handleDoubleClick(S32 x, S32 y, MASK mask)
00497 {
00498 return handleMouseDown(x, y, mask);
00499 }
00500
00501 BOOL LLToolCompCreate::handleMouseUp(S32 x, S32 y, MASK mask)
00502 {
00503 BOOL handled = FALSE;
00504
00505 if ( mMouseDown && !mObjectPlacedOnMouseDown && !(mask == MASK_SHIFT) && !(mask == MASK_CONTROL) )
00506 {
00507 setCurrentTool( mPlacer );
00508 handled = mPlacer->placeObject( x, y, mask );
00509 }
00510
00511 mObjectPlacedOnMouseDown = FALSE;
00512 mMouseDown = FALSE;
00513
00514 if (!handled)
00515 {
00516 handled = LLToolComposite::handleMouseUp(x, y, mask);
00517 }
00518
00519 return handled;
00520 }
00521
00522
00523
00524
00525 LLToolCompRotate::LLToolCompRotate()
00526 : LLToolComposite("Rotate")
00527 {
00528 mManip = new LLManipRotate(this);
00529 mSelectRect = new LLToolSelectRect(this);
00530
00531 mCur = mManip;
00532 mDefault = mManip;
00533 }
00534
00535
00536 LLToolCompRotate::~LLToolCompRotate()
00537 {
00538 delete mManip;
00539 delete mSelectRect;
00540 }
00541
00542 BOOL LLToolCompRotate::handleHover(S32 x, S32 y, MASK mask)
00543 {
00544 if( !mCur->hasMouseCapture() )
00545 {
00546 setCurrentTool( mManip );
00547 }
00548 return mCur->handleHover( x, y, mask );
00549 }
00550
00551
00552 BOOL LLToolCompRotate::handleMouseDown(S32 x, S32 y, MASK mask)
00553 {
00554 mMouseDown = TRUE;
00555 gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback);
00556 return TRUE;
00557 }
00558
00559 void LLToolCompRotate::pickCallback(S32 x, S32 y, MASK mask)
00560 {
00561 LLViewerObject* hit_obj = gViewerWindow->lastObjectHit();
00562
00563 gToolRotate->mManip->highlightManipulators(x, y);
00564 if (!gToolRotate->mMouseDown)
00565 {
00566
00567 gToolRotate->mSelectRect->handleObjectSelection(hit_obj, mask, gSavedSettings.getBOOL("EditLinkedParts"), FALSE);
00568 return;
00569 }
00570
00571 if( hit_obj || gToolRotate->mManip->getHighlightedPart() != LLManip::LL_NO_PART)
00572 {
00573 if (gToolRotate->mManip->getSelection()->getObjectCount())
00574 {
00575 gEditMenuHandler = gSelectMgr;
00576 }
00577 if( LLManip::LL_NO_PART != gToolRotate->mManip->getHighlightedPart() )
00578 {
00579 gToolRotate->setCurrentTool( gToolRotate->mManip );
00580 gToolRotate->mManip->handleMouseDownOnPart( x, y, mask );
00581 }
00582 else
00583 {
00584 gToolRotate->setCurrentTool( gToolRotate->mSelectRect );
00585 gToolRotate->mSelectRect->handleMouseDown( x, y, mask );
00586 }
00587 }
00588 else
00589 {
00590 gToolRotate->setCurrentTool( gToolRotate->mSelectRect );
00591 gToolRotate->mCur->handleMouseDown( x, y, mask );
00592 }
00593 }
00594
00595 BOOL LLToolCompRotate::handleMouseUp(S32 x, S32 y, MASK mask)
00596 {
00597 mMouseDown = FALSE;
00598 return LLToolComposite::handleMouseUp(x, y, mask);
00599 }
00600
00601 LLTool* LLToolCompRotate::getOverrideTool(MASK mask)
00602 {
00603 if (mask == (MASK_CONTROL | MASK_SHIFT))
00604 {
00605 return gToolStretch;
00606 }
00607 return LLToolComposite::getOverrideTool(mask);
00608 }
00609
00610 BOOL LLToolCompRotate::handleDoubleClick(S32 x, S32 y, MASK mask)
00611 {
00612 if (!mManip->getSelection()->isEmpty() && mManip->getHighlightedPart() == LLManip::LL_NO_PART)
00613 {
00614
00615
00616 gFloaterTools->showPanel(LLFloaterTools::PANEL_CONTENTS);
00617
00618 return TRUE;
00619 }
00620 else
00621 {
00622
00623
00624 return handleMouseDown(x, y, mask);
00625 }
00626 }
00627
00628
00629 void LLToolCompRotate::render()
00630 {
00631 mCur->render();
00632
00633 if( mCur != mManip )
00634 {
00635 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
00636 mManip->renderGuidelines();
00637 }
00638 }
00639
00640
00641
00642
00643
00644 LLToolCompGun::LLToolCompGun()
00645 : LLToolComposite("Mouselook")
00646 {
00647 mGun = new LLToolGun(this);
00648 mGrab = new LLToolGrab(this);
00649 mNull = new LLTool("null", this);
00650
00651 setCurrentTool(mGun);
00652 mDefault = mGun;
00653 }
00654
00655
00656 LLToolCompGun::~LLToolCompGun()
00657 {
00658 delete mGun;
00659 mGun = NULL;
00660
00661 delete mGrab;
00662 mGrab = NULL;
00663
00664 delete mNull;
00665 mNull = NULL;
00666 }
00667
00668 BOOL LLToolCompGun::handleHover(S32 x, S32 y, MASK mask)
00669 {
00670
00671
00672 if ( mCur == mNull && !gPopupMenuView->getVisible() )
00673 {
00674 gSelectMgr->deselectAll();
00675 setCurrentTool( (LLTool*) mGrab );
00676 }
00677
00678
00679
00680
00681
00682
00683 mCur->handleHover( x, y, mask );
00684
00685
00686 if( !gViewerWindow->getLeftMouseDown())
00687 {
00688
00689 if ( mCur == mGun && (mask & MASK_ALT) )
00690 {
00691 setCurrentTool( (LLTool*) mGrab );
00692 }
00693 else if ( mCur == mGrab && !(mask & MASK_ALT) )
00694 {
00695 setCurrentTool( (LLTool*) mGun );
00696 setMouseCapture(TRUE);
00697 }
00698 }
00699
00700 return TRUE;
00701 }
00702
00703
00704 BOOL LLToolCompGun::handleMouseDown(S32 x, S32 y, MASK mask)
00705 {
00706
00707 if (gAgent.leftButtonGrabbed())
00708 {
00709 gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN);
00710 return FALSE;
00711 }
00712
00713
00714 gGrabTransientTool = this;
00715 gToolMgr->getCurrentToolset()->selectTool( (LLTool*) mGrab );
00716
00717 return gToolGrab->handleMouseDown(x, y, mask);
00718 }
00719
00720
00721 BOOL LLToolCompGun::handleDoubleClick(S32 x, S32 y, MASK mask)
00722 {
00723
00724 if (gAgent.leftButtonGrabbed())
00725 {
00726 gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN);
00727 return FALSE;
00728 }
00729
00730
00731 gGrabTransientTool = this;
00732 gToolMgr->getCurrentToolset()->selectTool( (LLTool*) mGrab );
00733
00734 return gToolGrab->handleDoubleClick(x, y, mask);
00735 }
00736
00737
00738 BOOL LLToolCompGun::handleRightMouseDown(S32 x, S32 y, MASK mask)
00739 {
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752 return TRUE;
00753 }
00754
00755
00756 BOOL LLToolCompGun::handleMouseUp(S32 x, S32 y, MASK mask)
00757 {
00758 gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP);
00759 setCurrentTool( (LLTool*) mGun );
00760 return TRUE;
00761 }
00762
00763 void LLToolCompGun::onMouseCaptureLost()
00764 {
00765 if (mComposite)
00766 {
00767 mComposite->onMouseCaptureLost();
00768 return;
00769 }
00770 mCur->onMouseCaptureLost();
00771
00772
00773
00774 setCurrentTool( (LLTool*) mGun );
00775 }
00776
00777 void LLToolCompGun::handleSelect()
00778 {
00779 LLToolComposite::handleSelect();
00780 setMouseCapture(TRUE);
00781 }
00782
00783 void LLToolCompGun::handleDeselect()
00784 {
00785 LLToolComposite::handleDeselect();
00786 setMouseCapture(FALSE);
00787 }
00788
00789
00790 BOOL LLToolCompGun::handleScrollWheel(S32 x, S32 y, S32 clicks)
00791 {
00792 if (clicks > 0)
00793 {
00794 gAgent.changeCameraToDefault();
00795
00796 }
00797 return TRUE;
00798 }