00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "lltoolpie.h"
00035
00036 #include "indra_constants.h"
00037 #include "llclickaction.h"
00038 #include "llparcel.h"
00039
00040 #include "llagent.h"
00041 #include "llviewercontrol.h"
00042 #include "llfirstuse.h"
00043 #include "llfloateravatarinfo.h"
00044 #include "llfloaterland.h"
00045 #include "llfloaterscriptdebug.h"
00046 #include "llhoverview.h"
00047 #include "llhudeffecttrail.h"
00048 #include "llhudmanager.h"
00049 #include "llmenugl.h"
00050 #include "llmutelist.h"
00051 #include "llselectmgr.h"
00052 #include "lltoolfocus.h"
00053 #include "lltoolgrab.h"
00054 #include "lltoolmgr.h"
00055 #include "lltoolselect.h"
00056 #include "llviewercamera.h"
00057 #include "llviewermenu.h"
00058 #include "llviewerobject.h"
00059 #include "llviewerobjectlist.h"
00060 #include "llviewerparcelmgr.h"
00061 #include "llviewerwindow.h"
00062 #include "llvoavatar.h"
00063 #include "llworld.h"
00064 #include "llui.h"
00065
00066 LLToolPie *gToolPie = NULL;
00067
00068 LLPointer<LLViewerObject> LLToolPie::sClickActionObject;
00069 LLHandle<LLObjectSelection> LLToolPie::sLeftClickSelection = NULL;
00070 U8 LLToolPie::sClickAction = 0;
00071
00072 extern void handle_buy(void*);
00073
00074 extern BOOL gDebugClicks;
00075
00076 LLToolPie::LLToolPie()
00077 : LLTool("Select"),
00078 mPieMouseButtonDown( FALSE ),
00079 mGrabMouseButtonDown( FALSE ),
00080 mHitLand( FALSE ),
00081 mHitObjectID(),
00082 mMouseOutsideSlop( FALSE )
00083 { }
00084
00085
00086 BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
00087 {
00088
00089 gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, leftMouseCallback,
00090 TRUE, TRUE);
00091 mGrabMouseButtonDown = TRUE;
00092 return TRUE;
00093 }
00094
00095
00096 void LLToolPie::leftMouseCallback(S32 x, S32 y, MASK mask)
00097 {
00098 gToolPie->pickAndShowMenu(x, y, mask, FALSE);
00099 }
00100
00101 BOOL LLToolPie::handleRightMouseDown(S32 x, S32 y, MASK mask)
00102 {
00103
00104 gPickFaces = TRUE;
00105
00106 gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, rightMouseCallback,
00107 FALSE, TRUE);
00108 mPieMouseButtonDown = TRUE;
00109
00110 return FALSE;
00111 }
00112
00113
00114 void LLToolPie::rightMouseCallback(S32 x, S32 y, MASK mask)
00115 {
00116 gToolPie->pickAndShowMenu(x, y, mask, TRUE);
00117 }
00118
00119
00120 BOOL LLToolPie::pickAndShowMenu(S32 x, S32 y, MASK mask, BOOL always_show)
00121 {
00122 if (!always_show && gLastHitParcelWall)
00123 {
00124 LLParcel* parcel = gParcelMgr->getCollisionParcel();
00125 if (parcel)
00126 {
00127 gParcelMgr->selectCollisionParcel();
00128 if (parcel->getParcelFlag(PF_USE_PASS_LIST)
00129 && !gParcelMgr->isCollisionBanned())
00130 {
00131
00132 void* deselect_when_done = (void*)TRUE;
00133 LLPanelLandGeneral::onClickBuyPass(deselect_when_done);
00134 }
00135 else
00136 {
00137
00138 LLFloaterLand::show();
00139 }
00140 }
00141
00142 return LLTool::handleMouseDown(x, y, mask);
00143 }
00144
00145
00146 LLViewerObject *object = gViewerWindow->lastObjectHit();
00147 LLViewerObject *parent = NULL;
00148
00149 mHitLand = !object && !gLastHitPosGlobal.isExactlyZero();
00150 if (!mHitLand)
00151 {
00152 gParcelMgr->deselectLand();
00153 }
00154
00155 if (object)
00156 {
00157 mHitObjectID = object->mID;
00158
00159 parent = object->getRootEdit();
00160 }
00161 else
00162 {
00163 mHitObjectID.setNull();
00164 }
00165
00166 BOOL touchable = (object && object->flagHandleTouch())
00167 || (parent && parent->flagHandleTouch());
00168
00169
00170 if (useClickAction(always_show, mask, object, parent))
00171 {
00172 sClickAction = 0;
00173 if (object && object->getClickAction())
00174 {
00175 sClickAction = object->getClickAction();
00176 }
00177 else if (parent && parent->getClickAction())
00178 {
00179 sClickAction = parent->getClickAction();
00180 }
00181
00182 switch(sClickAction)
00183 {
00184 case CLICK_ACTION_TOUCH:
00185 default:
00186
00187 break;
00188 case CLICK_ACTION_SIT:
00189 handle_sit_or_stand();
00190 return TRUE;
00191 case CLICK_ACTION_PAY:
00192 if (object && object->flagTakesMoney()
00193 || parent && parent->flagTakesMoney())
00194 {
00195
00196 sClickActionObject = object;
00197 sLeftClickSelection = LLToolSelect::handleObjectSelection(object, MASK_NONE, FALSE, TRUE);
00198 return TRUE;
00199 }
00200 break;
00201 case CLICK_ACTION_BUY:
00202 sClickActionObject = parent;
00203 sLeftClickSelection = LLToolSelect::handleObjectSelection(parent, MASK_NONE, FALSE, TRUE);
00204 return TRUE;
00205 case CLICK_ACTION_OPEN:
00206 if (parent && parent->allowOpen())
00207 {
00208 sClickActionObject = parent;
00209 sLeftClickSelection = LLToolSelect::handleObjectSelection(parent, MASK_NONE, FALSE, TRUE);
00210 }
00211 return TRUE;
00212 }
00213 }
00214
00215
00216 if (object &&
00217 !object->isAvatar() &&
00218 ((object->usePhysics() || (parent && !parent->isAvatar() && parent->usePhysics())) || touchable) &&
00219 !always_show)
00220 {
00221 gGrabTransientTool = this;
00222 gToolMgr->getCurrentToolset()->selectTool( gToolGrab );
00223 return gToolGrab->handleObjectHit( object, x, y, mask);
00224 }
00225
00226 if (!object && gLastHitHUDIcon && gLastHitHUDIcon->getSourceObject())
00227 {
00228 LLFloaterScriptDebug::show(gLastHitHUDIcon->getSourceObject()->getID());
00229 }
00230
00231
00232
00233 if (!gSavedSettings.getBOOL("LeftClickShowMenu")
00234 && !always_show)
00235 {
00236
00237 if (!mGrabMouseButtonDown)
00238 {
00239 return TRUE;
00240 }
00241
00242 while( object && object->isAttachment() && !object->flagHandleTouch())
00243 {
00244
00245 if (object->isHUDAttachment())
00246 {
00247 break;
00248 }
00249 object = (LLViewerObject*)object->getParent();
00250 }
00251 if (object && object == gAgent.getAvatarObject())
00252 {
00253
00254 gToolMgr->setTransientTool(gToolCamera);
00255 gViewerWindow->hideCursor();
00256 gToolCamera->setMouseCapture(TRUE);
00257 gToolCamera->pickCallback(gViewerWindow->getCurrentMouseX(), gViewerWindow->getCurrentMouseY(), mask);
00258 gAgent.setFocusOnAvatar(TRUE, TRUE);
00259
00260 return TRUE;
00261 }
00262
00263 LLFirstUse::useLeftClickNoHit();
00264
00265
00266 return LLTool::handleMouseDown(x, y, mask);
00267 }
00268
00269 if (!always_show && gAgent.leftButtonGrabbed())
00270 {
00271
00272 return LLTool::handleMouseDown(x, y, mask);
00273 }
00274
00275
00276 LLToolSelect::handleObjectSelection(object, mask, FALSE, TRUE);
00277
00278
00279 if (mHitLand)
00280 {
00281 LLParcelSelectionHandle selection = gParcelMgr->selectParcelAt( gLastHitPosGlobal );
00282 gMenuHolder->setParcelSelection(selection);
00283 gPieLand->show(x, y, mPieMouseButtonDown);
00284
00285
00286 LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_SPHERE, TRUE);
00287 effectp->setPositionGlobal(gLastHitPosGlobal);
00288 effectp->setColor(LLColor4U(gAgent.getEffectColor()));
00289 effectp->setDuration(0.25f);
00290 }
00291 else if (mHitObjectID == gAgent.getID() )
00292 {
00293 gPieSelf->show(x, y, mPieMouseButtonDown);
00294 }
00295 else if (object)
00296 {
00297 gMenuHolder->setObjectSelection(gSelectMgr->getSelection());
00298
00299 if (object->isAvatar()
00300 || (object->isAttachment() && !object->isHUDAttachment() && !object->permYouOwner()))
00301 {
00302
00303 while( object && object->isAttachment())
00304 {
00305 object = (LLViewerObject*)object->getParent();
00306 }
00307
00308
00309 LLVOAvatar* avatar = (LLVOAvatar*)object;
00310 LLString name = avatar->getFullname();
00311 if (gMuteListp->isMuted(avatar->getID(), name))
00312 {
00313 gMenuHolder->childSetText("Avatar Mute", LLString("Unmute"));
00314
00315 }
00316 else
00317 {
00318 gMenuHolder->childSetText("Avatar Mute", LLString("Mute"));
00319
00320 }
00321
00322 gPieAvatar->show(x, y, mPieMouseButtonDown);
00323 }
00324 else if (object->isAttachment())
00325 {
00326 gPieAttachment->show(x, y, mPieMouseButtonDown);
00327 }
00328 else
00329 {
00330
00331 LLString name;
00332 LLSelectNode* node = gSelectMgr->getSelection()->getFirstRootNode();
00333 if (node)
00334 {
00335 name = node->mName;
00336 }
00337 if (gMuteListp->isMuted(object->getID(), name))
00338 {
00339 gMenuHolder->childSetText("Object Mute", LLString("Unmute"));
00340
00341 }
00342 else
00343 {
00344 gMenuHolder->childSetText("Object Mute", LLString("Mute"));
00345
00346 }
00347
00348 gPieObject->show(x, y, mPieMouseButtonDown);
00349
00350
00351
00352
00353 LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_SPHERE, TRUE);
00354 effectp->setPositionGlobal(gLastHitPosGlobal);
00355 effectp->setColor(LLColor4U(gAgent.getEffectColor()));
00356 effectp->setDuration(0.25f);
00357 }
00358 }
00359
00360 if (always_show)
00361 {
00362
00363 LLTool::handleRightMouseDown(x, y, mask);
00364 }
00365 else
00366 {
00367
00368 LLTool::handleMouseDown(x, y, mask);
00369 }
00370
00371
00372 return TRUE;
00373 }
00374
00375 BOOL LLToolPie::useClickAction(BOOL always_show,
00376 MASK mask,
00377 LLViewerObject* object,
00378 LLViewerObject* parent)
00379 {
00380 return !always_show
00381 && mask == MASK_NONE
00382 && object
00383 && !object->isAttachment()
00384 && LLPrimitive::isPrimitive(object->getPCode())
00385 && (object->getClickAction()
00386 || parent->getClickAction());
00387
00388 }
00389
00390 U8 final_click_action(LLViewerObject* obj)
00391 {
00392 if (!obj) return CLICK_ACTION_NONE;
00393 if (obj->isAttachment()) return CLICK_ACTION_NONE;
00394
00395 U8 click_action = CLICK_ACTION_TOUCH;
00396 LLViewerObject* parent = obj->getRootEdit();
00397 if (obj->getClickAction()
00398 || (parent && parent->getClickAction()))
00399 {
00400 if (obj->getClickAction())
00401 {
00402 click_action = obj->getClickAction();
00403 }
00404 else if (parent && parent->getClickAction())
00405 {
00406 click_action = parent->getClickAction();
00407 }
00408 }
00409 return click_action;
00410 }
00411
00412
00413
00414
00415 void LLToolPie::selectionPropertiesReceived()
00416 {
00417
00418
00419 if (!gSelectMgr->selectGetAllValid())
00420 {
00421 return;
00422 }
00423
00424 if (!sLeftClickSelection->isEmpty())
00425 {
00426 LLViewerObject* selected_object = sLeftClickSelection->getPrimaryObject();
00427
00428
00429 if (selected_object == sClickActionObject)
00430 {
00431 switch (sClickAction)
00432 {
00433 case CLICK_ACTION_BUY:
00434 handle_buy(NULL);
00435 break;
00436 case CLICK_ACTION_PAY:
00437 handle_give_money_dialog();
00438 break;
00439 case CLICK_ACTION_OPEN:
00440 handle_object_open();
00441 break;
00442 default:
00443 break;
00444 }
00445 }
00446 }
00447 sLeftClickSelection = NULL;
00448 sClickActionObject = NULL;
00449 sClickAction = 0;
00450 }
00451
00452 BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
00453 {
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473 LLViewerObject *object = NULL;
00474 LLViewerObject *parent = NULL;
00475 if (gHoverView)
00476 {
00477 object = gHoverView->getLastHoverObject();
00478 }
00479
00480 if (object)
00481 {
00482 parent = object->getRootEdit();
00483 }
00484
00485 if (object && useClickAction(FALSE, mask, object, parent))
00486 {
00487 U8 click_action = final_click_action(object);
00488 ECursorType cursor = UI_CURSOR_ARROW;
00489 switch(click_action)
00490 {
00491 default: break;
00492 case CLICK_ACTION_SIT: cursor = UI_CURSOR_TOOLSIT; break;
00493 case CLICK_ACTION_BUY: cursor = UI_CURSOR_TOOLBUY; break;
00494 case CLICK_ACTION_OPEN:
00495
00496 if (parent && parent->allowOpen())
00497 {
00498 cursor = UI_CURSOR_TOOLOPEN;
00499 }
00500 break;
00501 case CLICK_ACTION_PAY:
00502 if ((object && object->flagTakesMoney())
00503 || (parent && parent->flagTakesMoney()))
00504 {
00505 cursor = UI_CURSOR_TOOLPAY;
00506 }
00507 break;
00508 }
00509 gViewerWindow->getWindow()->setCursor(cursor);
00510 lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
00511 }
00512 else if ((object && !object->isAvatar() && object->usePhysics())
00513 || (parent && !parent->isAvatar() && parent->usePhysics()))
00514 {
00515 gViewerWindow->getWindow()->setCursor(UI_CURSOR_TOOLGRAB);
00516 lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
00517 }
00518 else if ( (object && object->flagHandleTouch())
00519 || (parent && parent->flagHandleTouch()))
00520 {
00521 gViewerWindow->getWindow()->setCursor(UI_CURSOR_HAND);
00522 lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
00523 }
00524 else
00525 {
00526 gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
00527 lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
00528 }
00529
00530 return TRUE;
00531 }
00532
00533 BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
00534 {
00535 LLViewerObject* obj = gViewerWindow->lastObjectHit();
00536 U8 click_action = final_click_action(obj);
00537 if (click_action != CLICK_ACTION_NONE)
00538 {
00539 switch(click_action)
00540 {
00541 case CLICK_ACTION_BUY:
00542 case CLICK_ACTION_PAY:
00543 case CLICK_ACTION_OPEN:
00544
00545
00546
00547
00548
00549 gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
00550
00551 gHoverView->resetLastHoverObject();
00552 break;
00553 default:
00554 break;
00555 }
00556 }
00557 mGrabMouseButtonDown = FALSE;
00558 gToolMgr->clearTransientTool();
00559 gAgent.setLookAt(LOOKAT_TARGET_CONVERSATION, obj);
00560 return LLTool::handleMouseUp(x, y, mask);
00561 }
00562
00563 BOOL LLToolPie::handleRightMouseUp(S32 x, S32 y, MASK mask)
00564 {
00565 mPieMouseButtonDown = FALSE;
00566 gToolMgr->clearTransientTool();
00567 return LLTool::handleRightMouseUp(x, y, mask);
00568 }
00569
00570
00571 BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask)
00572 {
00573 if (gDebugClicks)
00574 {
00575 llinfos << "LLToolPie handleDoubleClick (becoming mouseDown)" << llendl;
00576 }
00577
00578 if (gSavedSettings.getBOOL("DoubleClickAutoPilot"))
00579 {
00580 if (gLastHitLand
00581 && !gLastHitPosGlobal.isExactlyZero())
00582 {
00583 handle_go_to();
00584 return TRUE;
00585 }
00586 else if (gLastHitObjectID.notNull()
00587 && !gLastHitPosGlobal.isExactlyZero())
00588 {
00589
00590
00591 gLastHitPosGlobal += gLastHitObjectOffset;
00592 handle_go_to();
00593 return TRUE;
00594 }
00595 }
00596
00597 return FALSE;
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622 }
00623
00624
00625 void LLToolPie::handleDeselect()
00626 {
00627 if( hasMouseCapture() )
00628 {
00629 setMouseCapture( FALSE );
00630 }
00631
00632 gSelectMgr->validateSelection();
00633 }
00634
00635 LLTool* LLToolPie::getOverrideTool(MASK mask)
00636 {
00637 if (mask == MASK_CONTROL)
00638 {
00639 return gToolGrab;
00640 }
00641 else if (mask == (MASK_CONTROL | MASK_SHIFT))
00642 {
00643 return gToolGrab;
00644 }
00645
00646 return LLTool::getOverrideTool(mask);
00647 }
00648
00649 void LLToolPie::stopEditing()
00650 {
00651 if( hasMouseCapture() )
00652 {
00653 setMouseCapture( FALSE );
00654 }
00655 }
00656
00657 void LLToolPie::onMouseCaptureLost()
00658 {
00659 mMouseOutsideSlop = FALSE;
00660 }
00661
00662
00663
00664 BOOL LLToolPie::outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y)
00665 {
00666 S32 dx = x - start_x;
00667 S32 dy = y - start_y;
00668
00669 return (dx <= -2 || 2 <= dx || dy <= -2 || 2 <= dy);
00670 }
00671
00672
00673 void LLToolPie::render()
00674 {
00675 return;
00676 }
00677
00678