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