lltoolpie.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:40k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file lltoolpie.cpp
  3.  * @brief LLToolPie class implementation
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "lltoolpie.h"
  34. #include "indra_constants.h"
  35. #include "llclickaction.h"
  36. #include "llparcel.h"
  37. #include "llagent.h"
  38. #include "llviewercontrol.h"
  39. #include "llfocusmgr.h"
  40. //#include "llfirstuse.h"
  41. #include "llfloaterland.h"
  42. #include "llfloaterreg.h"
  43. #include "llfloaterscriptdebug.h"
  44. #include "lltooltip.h"
  45. #include "llhudeffecttrail.h"
  46. #include "llhudmanager.h"
  47. #include "llkeyboard.h"
  48. #include "llmediaentry.h"
  49. #include "llmenugl.h"
  50. #include "llmutelist.h"
  51. #include "llselectmgr.h"
  52. #include "lltoolfocus.h"
  53. #include "lltoolgrab.h"
  54. #include "lltoolmgr.h"
  55. #include "lltoolselect.h"
  56. #include "lltrans.h"
  57. #include "llviewercamera.h"
  58. #include "llviewerparcelmedia.h"
  59. #include "llviewermenu.h"
  60. #include "llviewerobjectlist.h"
  61. #include "llviewerobject.h"
  62. #include "llviewerparcelmgr.h"
  63. #include "llviewerwindow.h"
  64. #include "llviewermedia.h"
  65. #include "llvoavatarself.h"
  66. #include "llviewermediafocus.h"
  67. #include "llworld.h"
  68. #include "llui.h"
  69. #include "llweb.h"
  70. #include "pipeline.h" // setHighlightObject
  71. extern BOOL gDebugClicks;
  72. static void handle_click_action_play();
  73. static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp);
  74. static ECursorType cursor_from_parcel_media(U8 click_action);
  75. LLToolPie::LLToolPie()
  76. : LLTool(std::string("Pie")),
  77. mGrabMouseButtonDown( FALSE ),
  78. mMouseOutsideSlop( FALSE ),
  79. mClickAction(0)
  80. { }
  81. BOOL LLToolPie::handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down)
  82. {
  83. BOOL result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down);
  84. // This override DISABLES the keyboard focus reset that LLTool::handleAnyMouseClick adds.
  85. // LLToolPie will do the right thing in its pick callback.
  86. return result;
  87. }
  88. BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
  89. {
  90. //left mouse down always picks transparent
  91. mPick = gViewerWindow->pickImmediate(x, y, TRUE);
  92. mPick.mKeyMask = mask;
  93. mGrabMouseButtonDown = TRUE;
  94. pickLeftMouseDownCallback();
  95. return TRUE;
  96. }
  97. // Spawn context menus on right mouse down so you can drag over and select
  98. // an item.
  99. BOOL LLToolPie::handleRightMouseDown(S32 x, S32 y, MASK mask)
  100. {
  101. // don't pick transparent so users can't "pay" transparent objects
  102. mPick = gViewerWindow->pickImmediate(x, y, FALSE);
  103. mPick.mKeyMask = mask;
  104. // claim not handled so UI focus stays same
  105. pickRightMouseDownCallback();
  106. return FALSE;
  107. }
  108. BOOL LLToolPie::handleRightMouseUp(S32 x, S32 y, MASK mask)
  109. {
  110. LLToolMgr::getInstance()->clearTransientTool();
  111. return LLTool::handleRightMouseUp(x, y, mask);
  112. }
  113. BOOL LLToolPie::handleScrollWheel(S32 x, S32 y, S32 clicks)
  114. {
  115. return LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks);
  116. }
  117. // True if you selected an object.
  118. BOOL LLToolPie::pickLeftMouseDownCallback()
  119. {
  120. S32 x = mPick.mMousePt.mX;
  121. S32 y = mPick.mMousePt.mY;
  122. MASK mask = mPick.mKeyMask;
  123. if (mPick.mPickType == LLPickInfo::PICK_PARCEL_WALL)
  124. {
  125. LLParcel* parcel = LLViewerParcelMgr::getInstance()->getCollisionParcel();
  126. if (parcel)
  127. {
  128. LLViewerParcelMgr::getInstance()->selectCollisionParcel();
  129. if (parcel->getParcelFlag(PF_USE_PASS_LIST) 
  130. && !LLViewerParcelMgr::getInstance()->isCollisionBanned())
  131. {
  132. // if selling passes, just buy one
  133. void* deselect_when_done = (void*)TRUE;
  134. LLPanelLandGeneral::onClickBuyPass(deselect_when_done);
  135. }
  136. else
  137. {
  138. // not selling passes, get info
  139. LLFloaterReg::showInstance("about_land");
  140. }
  141. }
  142. gFocusMgr.setKeyboardFocus(NULL);
  143. return LLTool::handleMouseDown(x, y, mask);
  144. }
  145. // didn't click in any UI object, so must have clicked in the world
  146. LLViewerObject *object = mPick.getObject();
  147. LLViewerObject *parent = NULL;
  148. if (mPick.mPickType != LLPickInfo::PICK_LAND)
  149. {
  150. LLViewerParcelMgr::getInstance()->deselectLand();
  151. }
  152. if (object)
  153. {
  154. parent = object->getRootEdit();
  155. }
  156. BOOL touchable = (object && object->flagHandleTouch()) 
  157.  || (parent && parent->flagHandleTouch());
  158. // If it's a left-click, and we have a special action, do it.
  159. if (useClickAction(mask, object, parent))
  160. {
  161. mClickAction = 0;
  162. if (object && object->getClickAction()) 
  163. {
  164. mClickAction = object->getClickAction();
  165. }
  166. else if (parent && parent->getClickAction()) 
  167. {
  168. mClickAction = parent->getClickAction();
  169. }
  170. switch(mClickAction)
  171. {
  172. case CLICK_ACTION_TOUCH:
  173. // touch behavior down below...
  174. break;
  175. case CLICK_ACTION_SIT:
  176. if ((gAgent.getAvatarObject() != NULL) && (!gAgent.getAvatarObject()->isSitting())) // agent not already sitting
  177. {
  178. handle_object_sit_or_stand();
  179. // put focus in world when sitting on an object
  180. gFocusMgr.setKeyboardFocus(NULL);
  181. return TRUE;
  182. } // else nothing (fall through to touch)
  183. case CLICK_ACTION_PAY:
  184. if ((object && object->flagTakesMoney())
  185. || (parent && parent->flagTakesMoney()))
  186. {
  187. // pay event goes to object actually clicked on
  188. mClickActionObject = object;
  189. mLeftClickSelection = LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE);
  190. if (LLSelectMgr::getInstance()->selectGetAllValid())
  191. {
  192. // call this right away, since we have all the info we need to continue the action
  193. selectionPropertiesReceived();
  194. }
  195. return TRUE;
  196. }
  197. break;
  198. case CLICK_ACTION_BUY:
  199. mClickActionObject = parent;
  200. mLeftClickSelection = LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE, TRUE);
  201. if (LLSelectMgr::getInstance()->selectGetAllValid())
  202. {
  203. // call this right away, since we have all the info we need to continue the action
  204. selectionPropertiesReceived();
  205. }
  206. return TRUE;
  207. case CLICK_ACTION_OPEN:
  208. if (parent && parent->allowOpen())
  209. {
  210. mClickActionObject = parent;
  211. mLeftClickSelection = LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE, TRUE);
  212. if (LLSelectMgr::getInstance()->selectGetAllValid())
  213. {
  214. // call this right away, since we have all the info we need to continue the action
  215. selectionPropertiesReceived();
  216. }
  217. }
  218. return TRUE;
  219. case CLICK_ACTION_PLAY:
  220. handle_click_action_play();
  221. return TRUE;
  222. case CLICK_ACTION_OPEN_MEDIA:
  223. // mClickActionObject = object;
  224. handle_click_action_open_media(object);
  225. return TRUE;
  226. case CLICK_ACTION_ZOOM:
  227. {
  228. const F32 PADDING_FACTOR = 2.f;
  229. LLViewerObject* object = gObjectList.findObject(mPick.mObjectID);
  230. if (object)
  231. {
  232. gAgent.setFocusOnAvatar(FALSE, ANIMATE);
  233. LLBBox bbox = object->getBoundingBoxAgent() ;
  234. F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getAspect() > 1.f ? LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect() : LLViewerCamera::getInstance()->getView());
  235. F32 distance = bbox.getExtentLocal().magVec() * PADDING_FACTOR / atan(angle_of_view);
  236. LLVector3 obj_to_cam = LLViewerCamera::getInstance()->getOrigin() - bbox.getCenterAgent();
  237. obj_to_cam.normVec();
  238. LLVector3d object_center_global = gAgent.getPosGlobalFromAgent(bbox.getCenterAgent());
  239. gAgent.setCameraPosAndFocusGlobal(object_center_global + LLVector3d(obj_to_cam * distance), 
  240.   object_center_global, 
  241.   mPick.mObjectID );
  242. }
  243. }
  244. return TRUE;
  245. default:
  246. // nothing
  247. break;
  248. }
  249. }
  250. if (handleMediaClick(mPick))
  251. {
  252. return TRUE;
  253. }
  254. // put focus back "in world"
  255. gFocusMgr.setKeyboardFocus(NULL);
  256. // Switch to grab tool if physical or triggerable
  257. if (object && 
  258. !object->isAvatar() && 
  259. ((object->usePhysics() || (parent && !parent->isAvatar() && parent->usePhysics())) || touchable) 
  260. )
  261. {
  262. gGrabTransientTool = this;
  263. LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolGrab::getInstance() );
  264. return LLToolGrab::getInstance()->handleObjectHit( mPick );
  265. }
  266. LLHUDIcon* last_hit_hud_icon = mPick.mHUDIcon;
  267. if (!object && last_hit_hud_icon && last_hit_hud_icon->getSourceObject())
  268. {
  269. LLFloaterScriptDebug::show(last_hit_hud_icon->getSourceObject()->getID());
  270. }
  271. // If left-click never selects or spawns a menu
  272. // Eat the event.
  273. if (!gSavedSettings.getBOOL("LeftClickShowMenu"))
  274. {
  275. // mouse already released
  276. if (!mGrabMouseButtonDown)
  277. {
  278. return TRUE;
  279. }
  280. while( object && object->isAttachment() && !object->flagHandleTouch())
  281. {
  282. // don't pick avatar through hud attachment
  283. if (object->isHUDAttachment())
  284. {
  285. break;
  286. }
  287. object = (LLViewerObject*)object->getParent();
  288. }
  289. if (object && object == gAgent.getAvatarObject())
  290. {
  291. // we left clicked on avatar, switch to focus mode
  292. LLToolMgr::getInstance()->setTransientTool(LLToolCamera::getInstance());
  293. gViewerWindow->hideCursor();
  294. LLToolCamera::getInstance()->setMouseCapture(TRUE);
  295. LLToolCamera::getInstance()->pickCallback(mPick);
  296. gAgent.setFocusOnAvatar(TRUE, TRUE);
  297. return TRUE;
  298. }
  299. //////////
  300. // // Could be first left-click on nothing
  301. // LLFirstUse::useLeftClickNoHit();
  302. /////////
  303. // Eat the event
  304. return LLTool::handleMouseDown(x, y, mask);
  305. }
  306. if (gAgent.leftButtonGrabbed())
  307. {
  308. // if the left button is grabbed, don't put up the pie menu
  309. return LLTool::handleMouseDown(x, y, mask);
  310. }
  311. // Can't ignore children here.
  312. LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE);
  313. // Spawn pie menu
  314. LLTool::handleRightMouseDown(x, y, mask);
  315. return TRUE;
  316. }
  317. BOOL LLToolPie::useClickAction(MASK mask, 
  318.    LLViewerObject* object, 
  319.    LLViewerObject* parent)
  320. {
  321. return mask == MASK_NONE
  322. && object
  323. && !object->isAttachment() 
  324. && LLPrimitive::isPrimitive(object->getPCode())
  325. && (object->getClickAction() 
  326. || parent->getClickAction());
  327. }
  328. U8 final_click_action(LLViewerObject* obj)
  329. {
  330. if (!obj) return CLICK_ACTION_NONE;
  331. if (obj->isAttachment()) return CLICK_ACTION_NONE;
  332. U8 click_action = CLICK_ACTION_TOUCH;
  333. LLViewerObject* parent = obj->getRootEdit();
  334. if (obj->getClickAction()
  335.     || (parent && parent->getClickAction()))
  336. {
  337. if (obj->getClickAction())
  338. {
  339. click_action = obj->getClickAction();
  340. }
  341. else if (parent && parent->getClickAction())
  342. {
  343. click_action = parent->getClickAction();
  344. }
  345. }
  346. return click_action;
  347. }
  348. ECursorType cursor_from_object(LLViewerObject* object)
  349. {
  350. LLViewerObject* parent = NULL;
  351. if (object)
  352. {
  353. parent = object->getRootEdit();
  354. }
  355. U8 click_action = final_click_action(object);
  356. ECursorType cursor = UI_CURSOR_ARROW;
  357. switch(click_action)
  358. {
  359. case CLICK_ACTION_SIT:
  360. if ((gAgent.getAvatarObject() != NULL) && (!gAgent.getAvatarObject()->isSitting())) // not already sitting?
  361. {
  362. cursor = UI_CURSOR_HAND;
  363. }
  364. break;
  365. case CLICK_ACTION_BUY:
  366. cursor = UI_CURSOR_HAND;
  367. break;
  368. case CLICK_ACTION_OPEN:
  369. // Open always opens the parent.
  370. if (parent && parent->allowOpen())
  371. {
  372. cursor = UI_CURSOR_HAND;
  373. }
  374. break;
  375. case CLICK_ACTION_PAY:
  376. if ((object && object->flagTakesMoney())
  377. || (parent && parent->flagTakesMoney()))
  378. {
  379. cursor = UI_CURSOR_HAND;
  380. }
  381. break;
  382. case CLICK_ACTION_ZOOM:
  383. cursor = UI_CURSOR_TOOLZOOMIN;
  384. break;
  385. case CLICK_ACTION_PLAY:
  386. case CLICK_ACTION_OPEN_MEDIA: 
  387. cursor = cursor_from_parcel_media(click_action);
  388. break;
  389. default:
  390. break;
  391. }
  392. return cursor;
  393. }
  394. void LLToolPie::resetSelection()
  395. {
  396. mLeftClickSelection = NULL;
  397. mClickActionObject = NULL;
  398. mClickAction = 0;
  399. }
  400. // When we get object properties after left-clicking on an object
  401. // with left-click = buy, if it's the same object, do the buy.
  402. // static
  403. void LLToolPie::selectionPropertiesReceived()
  404. {
  405. // Make sure all data has been received.
  406. // This function will be called repeatedly as the data comes in.
  407. if (!LLSelectMgr::getInstance()->selectGetAllValid())
  408. {
  409. return;
  410. }
  411. LLObjectSelection* selection = LLToolPie::getInstance()->getLeftClickSelection();
  412. if (selection)
  413. {
  414. LLViewerObject* selected_object = selection->getPrimaryObject();
  415. // since we don't currently have a way to lock a selection, it could have changed
  416. // after we initially clicked on the object
  417. if (selected_object == LLToolPie::getInstance()->getClickActionObject())
  418. {
  419. U8 click_action = LLToolPie::getInstance()->getClickAction();
  420. switch (click_action)
  421. {
  422. case CLICK_ACTION_BUY:
  423. handle_buy();
  424. break;
  425. case CLICK_ACTION_PAY:
  426. handle_give_money_dialog();
  427. break;
  428. case CLICK_ACTION_OPEN:
  429. LLFloaterReg::showInstance("openobject");
  430. break;
  431. default:
  432. break;
  433. }
  434. }
  435. }
  436. LLToolPie::getInstance()->resetSelection();
  437. }
  438. BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
  439. {
  440. mHoverPick = gViewerWindow->pickImmediate(x, y, FALSE);
  441. // Show screen-space highlight glow effect
  442. bool show_highlight = false;
  443. LLViewerObject *parent = NULL;
  444. LLViewerObject *object = mHoverPick.getObject();
  445. if (object)
  446. {
  447. parent = object->getRootEdit();
  448. }
  449. if (object && useClickAction(mask, object, parent))
  450. {
  451. show_highlight = true;
  452. ECursorType cursor = cursor_from_object(object);
  453. gViewerWindow->setCursor(cursor);
  454. lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
  455. }
  456. else if (handleMediaHover(mHoverPick))
  457. {
  458. // *NOTE: If you think the hover glow conflicts with the media outline, you
  459. // could disable it here.
  460. show_highlight = true;
  461. // cursor set by media object
  462. lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
  463. }
  464. else if ((object && !object->isAvatar() && object->usePhysics()) 
  465.  || (parent && !parent->isAvatar() && parent->usePhysics()))
  466. {
  467. show_highlight = true;
  468. gViewerWindow->setCursor(UI_CURSOR_TOOLGRAB);
  469. lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
  470. }
  471. else if ( (object && object->flagHandleTouch()) 
  472.   || (parent && parent->flagHandleTouch()))
  473. {
  474. show_highlight = true;
  475. gViewerWindow->setCursor(UI_CURSOR_HAND);
  476. lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
  477. }
  478. else
  479. {
  480. gViewerWindow->setCursor(UI_CURSOR_ARROW);
  481. lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
  482. if(!object)
  483. {
  484. LLViewerMediaFocus::getInstance()->clearHover();
  485. }
  486. }
  487. static LLCachedControl<bool> enable_highlight(
  488. gSavedSettings, "RenderHoverGlowEnable", false);
  489. LLDrawable* drawable = NULL;
  490. if (enable_highlight && show_highlight && object)
  491. {
  492. drawable = object->mDrawable;
  493. }
  494. gPipeline.setHighlightObject(drawable);
  495. return TRUE;
  496. }
  497. BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
  498. {
  499. LLViewerObject* obj = mPick.getObject();
  500. handleMediaMouseUp();
  501. U8 click_action = final_click_action(obj);
  502. if (click_action != CLICK_ACTION_NONE)
  503. {
  504. switch(click_action)
  505. {
  506. case CLICK_ACTION_BUY:
  507. case CLICK_ACTION_PAY:
  508. case CLICK_ACTION_OPEN:
  509. case CLICK_ACTION_ZOOM:
  510. case CLICK_ACTION_PLAY:
  511. case CLICK_ACTION_OPEN_MEDIA:
  512. // Because these actions open UI dialogs, we won't change
  513. // the cursor again until the next hover and GL pick over
  514. // the world.  Keep the cursor an arrow, assuming that 
  515. // after the user moves off the UI, they won't be on the
  516. // same object anymore.
  517. gViewerWindow->setCursor(UI_CURSOR_ARROW);
  518. // Make sure the hover-picked object is ignored.
  519. //gToolTipView->resetLastHoverObject();
  520. break;
  521. default:
  522. break;
  523. }
  524. }
  525. mGrabMouseButtonDown = FALSE;
  526. LLToolMgr::getInstance()->clearTransientTool();
  527. gAgent.setLookAt(LOOKAT_TARGET_CONVERSATION, obj); // maybe look at object/person clicked on
  528. return LLTool::handleMouseUp(x, y, mask);
  529. }
  530. BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask)
  531. {
  532. if (gDebugClicks)
  533. {
  534. llinfos << "LLToolPie handleDoubleClick (becoming mouseDown)" << llendl;
  535. }
  536. if (gSavedSettings.getBOOL("DoubleClickAutoPilot"))
  537. {
  538. if (mPick.mPickType == LLPickInfo::PICK_LAND
  539. && !mPick.mPosGlobal.isExactlyZero())
  540. {
  541. handle_go_to();
  542. return TRUE;
  543. }
  544. else if (mPick.mObjectID.notNull()
  545.  && !mPick.mPosGlobal.isExactlyZero())
  546. {
  547. handle_go_to();
  548. return TRUE;
  549. }
  550. }
  551. return FALSE;
  552. }
  553. static bool needs_tooltip(LLSelectNode* nodep)
  554. {
  555. if (!nodep) 
  556. return false;
  557. LLViewerObject* object = nodep->getObject();
  558. LLViewerObject *parent = (LLViewerObject *)object->getParent();
  559. if (object->flagHandleTouch()
  560. || (parent && parent->flagHandleTouch())
  561. || object->flagTakesMoney()
  562. || (parent && parent->flagTakesMoney())
  563. || object->flagAllowInventoryAdd()
  564. )
  565. {
  566. return true;
  567. }
  568. U8 click_action = final_click_action(object);
  569. if (click_action != 0)
  570. {
  571. return true;
  572. }
  573. if (nodep->mValid)
  574. {
  575. bool anyone_copy = anyone_copy_selection(nodep);
  576. bool for_sale = for_sale_selection(nodep);
  577. if (anyone_copy || for_sale)
  578. {
  579. return true;
  580. }
  581. }
  582. return false;
  583. }
  584. BOOL LLToolPie::handleTooltipLand(std::string line, std::string tooltip_msg)
  585. {
  586. LLViewerParcelMgr::getInstance()->setHoverParcel( mHoverPick.mPosGlobal );
  587. // 
  588. //  Do not show hover for land unless prefs are set to allow it.
  589. // 
  590. if (!gSavedSettings.getBOOL("ShowLandHoverTip")) return TRUE; 
  591. // Didn't hit an object, but since we have a land point we
  592. // must be hovering over land.
  593. LLParcel* hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
  594. LLUUID owner;
  595. S32 width = 0;
  596. S32 height = 0;
  597. if ( hover_parcel )
  598. {
  599. owner = hover_parcel->getOwnerID();
  600. width = S32(LLViewerParcelMgr::getInstance()->getHoverParcelWidth());
  601. height = S32(LLViewerParcelMgr::getInstance()->getHoverParcelHeight());
  602. }
  603. // Line: "Land"
  604. line.clear();
  605. line.append(LLTrans::getString("TooltipLand"));
  606. if (hover_parcel)
  607. {
  608. line.append(hover_parcel->getName());
  609. }
  610. tooltip_msg.append(line);
  611. tooltip_msg.push_back('n');
  612. // Line: "Owner: James Linden"
  613. line.clear();
  614. line.append(LLTrans::getString("TooltipOwner") + " ");
  615. if ( hover_parcel )
  616. {
  617. std::string name;
  618. if (LLUUID::null == owner)
  619. {
  620. line.append(LLTrans::getString("TooltipPublic"));
  621. }
  622. else if (hover_parcel->getIsGroupOwned())
  623. {
  624. if (gCacheName->getGroupName(owner, name))
  625. {
  626. line.append(name);
  627. line.append(LLTrans::getString("TooltipIsGroup"));
  628. }
  629. else
  630. {
  631. line.append(LLTrans::getString("RetrievingData"));
  632. }
  633. }
  634. else if(gCacheName->getFullName(owner, name))
  635. {
  636. line.append(name);
  637. }
  638. else
  639. {
  640. line.append(LLTrans::getString("RetrievingData"));
  641. }
  642. }
  643. else
  644. {
  645. line.append(LLTrans::getString("RetrievingData"));
  646. }
  647. tooltip_msg.append(line);
  648. tooltip_msg.push_back('n');
  649. // Line: "no fly, not safe, no build"
  650. // Don't display properties for your land.  This is just
  651. // confusing, because you can do anything on your own land.
  652. if ( hover_parcel && owner != gAgent.getID() )
  653. {
  654. S32 words = 0;
  655. line.clear();
  656. // JC - Keep this in the same order as the checkboxes
  657. // on the land info panel
  658. if ( !hover_parcel->getAllowModify() )
  659. {
  660. if ( hover_parcel->getAllowGroupModify() )
  661. {
  662. line.append(LLTrans::getString("TooltipFlagGroupBuild"));
  663. }
  664. else
  665. {
  666. line.append(LLTrans::getString("TooltipFlagNoBuild"));
  667. }
  668. words++;
  669. }
  670. if ( !hover_parcel->getAllowTerraform() )
  671. {
  672. if (words) line.append(", ");
  673. line.append(LLTrans::getString("TooltipFlagNoEdit"));
  674. words++;
  675. }
  676. if ( hover_parcel->getAllowDamage() )
  677. {
  678. if (words) line.append(", ");
  679. line.append(LLTrans::getString("TooltipFlagNotSafe"));
  680. words++;
  681. }
  682. // Maybe we should reflect the estate's block fly bit here as well?  DK 12/1/04
  683. if ( !hover_parcel->getAllowFly() )
  684. {
  685. if (words) line.append(", ");
  686. line.append(LLTrans::getString("TooltipFlagNoFly"));
  687. words++;
  688. }
  689. if ( !hover_parcel->getAllowOtherScripts() )
  690. {
  691. if (words) line.append(", ");
  692. if ( hover_parcel->getAllowGroupScripts() )
  693. {
  694. line.append(LLTrans::getString("TooltipFlagGroupScripts"));
  695. }
  696. else
  697. {
  698. line.append(LLTrans::getString("TooltipFlagNoScripts"));
  699. }
  700. words++;
  701. }
  702. if (words) 
  703. {
  704. tooltip_msg.append(line);
  705. tooltip_msg.push_back('n');
  706. }
  707. }
  708. if (hover_parcel && hover_parcel->getParcelFlag(PF_FOR_SALE))
  709. {
  710. LLStringUtil::format_map_t args;
  711. args["[AMOUNT]"] = llformat("%d", hover_parcel->getSalePrice());
  712. line = LLTrans::getString("TooltipForSaleL$", args);
  713. tooltip_msg.append(line);
  714. tooltip_msg.push_back('n');
  715. }
  716. // trim last newlines
  717. if (!tooltip_msg.empty())
  718. {
  719. tooltip_msg.erase(tooltip_msg.size() - 1);
  720. LLToolTipMgr::instance().show(tooltip_msg);
  721. }
  722. return TRUE;
  723. }
  724. BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string line, std::string tooltip_msg)
  725. {
  726. if ( hover_object->isHUDAttachment() )
  727. {
  728. // no hover tips for HUD elements, since they can obscure
  729. // what the HUD is displaying
  730. return TRUE;
  731. }
  732. if ( hover_object->isAttachment() )
  733. {
  734. // get root of attachment then parent, which is avatar
  735. LLViewerObject* root_edit = hover_object->getRootEdit();
  736. if (!root_edit)
  737. {
  738. // Strange parenting issue, don't show any text
  739. return TRUE;
  740. }
  741. hover_object = (LLViewerObject*)root_edit->getParent();
  742. if (!hover_object)
  743. {
  744. // another strange parenting issue, bail out
  745. return TRUE;
  746. }
  747. }
  748. line.clear();
  749. if (hover_object->isAvatar())
  750. {
  751. // only show tooltip if same inspector not already open
  752. LLFloater* existing_inspector = LLFloaterReg::findInstance("inspect_avatar");
  753. if (!existing_inspector 
  754. || !existing_inspector->getVisible()
  755. || existing_inspector->getKey()["avatar_id"].asUUID() != hover_object->getID())
  756. {
  757. std::string avatar_name;
  758. LLNameValue* firstname = hover_object->getNVPair("FirstName");
  759. LLNameValue* lastname =  hover_object->getNVPair("LastName");
  760. if (firstname && lastname)
  761. {
  762. avatar_name = llformat("%s %s", firstname->getString(), lastname->getString());
  763. }
  764. else
  765. {
  766. avatar_name = LLTrans::getString("TooltipPerson");
  767. }
  768. // *HACK: We may select this object, so pretend it was clicked
  769. mPick = mHoverPick;
  770. LLInspector::Params p;
  771. p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>());
  772. p.message(avatar_name);
  773. p.image.name("Inspector_I");
  774. p.click_callback(boost::bind(showAvatarInspector, hover_object->getID()));
  775. p.visible_time_near(6.f);
  776. p.visible_time_far(3.f);
  777. p.delay_time(0.35f);
  778. p.wrap(false);
  779. LLToolTipMgr::instance().show(p);
  780. }
  781. }
  782. else
  783. {
  784. //
  785. //  We have hit a regular object (not an avatar or attachment)
  786. // 
  787. //
  788. //  Default prefs will suppress display unless the object is interactive
  789. //
  790. bool show_all_object_tips =
  791. (bool)gSavedSettings.getBOOL("ShowAllObjectHoverTip");
  792. LLSelectNode *nodep = LLSelectMgr::getInstance()->getHoverNode();
  793. // only show tooltip if same inspector not already open
  794. LLFloater* existing_inspector = LLFloaterReg::findInstance("inspect_object");
  795. if (nodep &&
  796. (!existing_inspector 
  797.  || !existing_inspector->getVisible()
  798.  || existing_inspector->getKey()["object_id"].asUUID() != hover_object->getID()))
  799. {
  800. if (nodep->mName.empty())
  801. {
  802. tooltip_msg.append(LLTrans::getString("TooltipNoName"));
  803. }
  804. else
  805. {
  806. tooltip_msg.append( nodep->mName );
  807. }
  808. bool has_media = false;
  809. bool is_time_based_media = false;
  810. bool is_web_based_media = false;
  811. bool is_media_playing = false;
  812. bool is_media_displaying = false;
  813. // Does this face have media?
  814. const LLTextureEntry* tep = hover_object->getTE(mHoverPick.mObjectFace);
  815. if(tep)
  816. {
  817. has_media = tep->hasMedia();
  818. const LLMediaEntry* mep = has_media ? tep->getMediaData() : NULL;
  819. if (mep)
  820. {
  821. viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
  822. LLPluginClassMedia* media_plugin = NULL;
  823. if (media_impl.notNull() && (media_impl->hasMedia()))
  824. {
  825. is_media_displaying = true;
  826. LLStringUtil::format_map_t args;
  827. media_plugin = media_impl->getMediaPlugin();
  828. if(media_plugin)
  829. {
  830. if(media_plugin->pluginSupportsMediaTime())
  831. {
  832. is_time_based_media = true;
  833. is_web_based_media = false;
  834. //args["[CurrentURL]"] =  media_impl->getMediaURL();
  835. is_media_playing = media_impl->isMediaPlaying();
  836. }
  837. else
  838. {
  839. is_time_based_media = false;
  840. is_web_based_media = true;
  841. //args["[CurrentURL]"] =  media_plugin->getLocation();
  842. }
  843. //tooltip_msg.append(LLTrans::getString("CurrentURL", args));
  844. }
  845. }
  846. }
  847. }
  848. // Avoid showing tip over media that's displaying
  849. // also check the primary node since sometimes it can have an action even though
  850. // the root node doesn't
  851. bool needs_tip = !is_media_displaying &&
  852. (has_media || 
  853.  needs_tooltip(nodep) || 
  854.  needs_tooltip(LLSelectMgr::getInstance()->getPrimaryHoverNode()));
  855. if (show_all_object_tips || needs_tip)
  856. {
  857. // We may select this object, so pretend it was clicked
  858. mPick = mHoverPick;
  859. LLInspector::Params p;
  860. p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>());
  861. p.message(tooltip_msg);
  862. p.image.name("Inspector_I");
  863. p.click_callback(boost::bind(showObjectInspector, hover_object->getID(), mHoverPick.mObjectFace));
  864. p.time_based_media(is_time_based_media);
  865. p.web_based_media(is_web_based_media);
  866. p.media_playing(is_media_playing);
  867. p.click_playmedia_callback(boost::bind(playCurrentMedia, mHoverPick));
  868. p.click_homepage_callback(boost::bind(VisitHomePage, mHoverPick));
  869. p.visible_time_near(6.f);
  870. p.visible_time_far(3.f);
  871. p.delay_time(0.35f);
  872. p.wrap(false);
  873. LLToolTipMgr::instance().show(p);
  874. }
  875. }
  876. }
  877. return TRUE;
  878. }
  879. BOOL LLToolPie::handleToolTip(S32 local_x, S32 local_y, MASK mask)
  880. {
  881. if (!LLUI::sSettingGroups["config"]->getBOOL("ShowHoverTips")) return TRUE;
  882. if (!mHoverPick.isValid()) return TRUE;
  883. LLViewerObject* hover_object = mHoverPick.getObject();
  884. // update hover object and hover parcel
  885. LLSelectMgr::getInstance()->setHoverObject(hover_object, mHoverPick.mObjectFace);
  886. std::string tooltip_msg;
  887. std::string line;
  888. if ( hover_object )
  889. {
  890. handleTooltipObject(hover_object, line, tooltip_msg  );
  891. }
  892. else if (mHoverPick.mPickType == LLPickInfo::PICK_LAND)
  893. {
  894. handleTooltipLand(line, tooltip_msg);
  895. }
  896. return TRUE;
  897. }
  898. static void show_inspector(const char* inspector, const char* param, const LLUUID& source_id)
  899. {
  900. LLSD params;
  901. params[param] = source_id;
  902. if (LLToolTipMgr::instance().toolTipVisible())
  903. {
  904. LLRect rect = LLToolTipMgr::instance().getToolTipRect();
  905. params["pos"]["x"] = rect.mLeft;
  906. params["pos"]["y"] = rect.mTop;
  907. }
  908. LLFloaterReg::showInstance(inspector, params);
  909. }
  910. static void show_inspector(const char* inspector,  LLSD& params)
  911. {
  912. if (LLToolTipMgr::instance().toolTipVisible())
  913. {
  914. LLRect rect = LLToolTipMgr::instance().getToolTipRect();
  915. params["pos"]["x"] = rect.mLeft;
  916. params["pos"]["y"] = rect.mTop;
  917. }
  918. LLFloaterReg::showInstance(inspector, params);
  919. }
  920. // static
  921. void LLToolPie::showAvatarInspector(const LLUUID& avatar_id)
  922. {
  923. show_inspector("inspect_avatar", "avatar_id", avatar_id);
  924. }
  925. // static
  926. void LLToolPie::showObjectInspector(const LLUUID& object_id)
  927. {
  928. show_inspector("inspect_object", "object_id", object_id);
  929. }
  930. // static
  931. void LLToolPie::showObjectInspector(const LLUUID& object_id, const S32& object_face)
  932. {
  933. LLSD params;
  934. params["object_id"] = object_id;
  935. params["object_face"] = object_face;
  936. show_inspector("inspect_object", params);
  937. }
  938. // static
  939. void LLToolPie::playCurrentMedia(const LLPickInfo& info)
  940. {
  941. //FIXME: how do we handle object in different parcel than us?
  942. LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
  943. if (!parcel) return;
  944. LLPointer<LLViewerObject> objectp = info.getObject();
  945. // Early out cases.  Must clear media hover. 
  946. // did not hit an object or did not hit a valid face
  947. if ( objectp.isNull() ||
  948. info.mObjectFace < 0 || 
  949. info.mObjectFace >= objectp->getNumTEs() )
  950. {
  951. return;
  952. }
  953. // Does this face have media?
  954. const LLTextureEntry* tep = objectp->getTE(info.mObjectFace);
  955. if (!tep)
  956. return;
  957. const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL;
  958. if(!mep)
  959. return;
  960. //TODO: Can you Use it? 
  961. LLPluginClassMedia* media_plugin = NULL;
  962. viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
  963. if(media_impl.notNull() && media_impl->hasMedia())
  964. {
  965. media_plugin = media_impl->getMediaPlugin();
  966. if (media_plugin && media_plugin->pluginSupportsMediaTime())
  967. {
  968. if(media_impl->isMediaPlaying())
  969. {
  970. media_impl->pause();
  971. }
  972. else 
  973. {
  974. media_impl->play();
  975. }
  976. }
  977. }
  978. }
  979. // static
  980. void LLToolPie::VisitHomePage(const LLPickInfo& info)
  981. {
  982. //FIXME: how do we handle object in different parcel than us?
  983. LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
  984. if (!parcel) return;
  985. LLPointer<LLViewerObject> objectp = info.getObject();
  986. // Early out cases.  Must clear media hover. 
  987. // did not hit an object or did not hit a valid face
  988. if ( objectp.isNull() ||
  989. info.mObjectFace < 0 || 
  990. info.mObjectFace >= objectp->getNumTEs() )
  991. {
  992. return;
  993. }
  994. // Does this face have media?
  995. const LLTextureEntry* tep = objectp->getTE(info.mObjectFace);
  996. if (!tep)
  997. return;
  998. const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL;
  999. if(!mep)
  1000. return;
  1001. //TODO: Can you Use it? 
  1002. LLPluginClassMedia* media_plugin = NULL;
  1003. viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
  1004. if(media_impl.notNull() && media_impl->hasMedia())
  1005. {
  1006. media_plugin = media_impl->getMediaPlugin();
  1007. if (media_plugin && !(media_plugin->pluginSupportsMediaTime()))
  1008. {
  1009. media_impl->navigateHome();
  1010. }
  1011. }
  1012. }
  1013. void LLToolPie::handleDeselect()
  1014. {
  1015. if( hasMouseCapture() )
  1016. {
  1017. setMouseCapture( FALSE );  // Calls onMouseCaptureLost() indirectly
  1018. }
  1019. // remove temporary selection for pie menu
  1020. LLSelectMgr::getInstance()->setHoverObject(NULL);
  1021. LLSelectMgr::getInstance()->validateSelection();
  1022. }
  1023. LLTool* LLToolPie::getOverrideTool(MASK mask)
  1024. {
  1025. if (mask == MASK_CONTROL)
  1026. {
  1027. return LLToolGrab::getInstance();
  1028. }
  1029. else if (mask == (MASK_CONTROL | MASK_SHIFT))
  1030. {
  1031. return LLToolGrab::getInstance();
  1032. }
  1033. return LLTool::getOverrideTool(mask);
  1034. }
  1035. void LLToolPie::stopEditing()
  1036. {
  1037. if( hasMouseCapture() )
  1038. {
  1039. setMouseCapture( FALSE );  // Calls onMouseCaptureLost() indirectly
  1040. }
  1041. }
  1042. void LLToolPie::onMouseCaptureLost()
  1043. {
  1044. mMouseOutsideSlop = FALSE;
  1045. handleMediaMouseUp();
  1046. }
  1047. // true if x,y outside small box around start_x,start_y
  1048. BOOL LLToolPie::outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y)
  1049. {
  1050. S32 dx = x - start_x;
  1051. S32 dy = y - start_y;
  1052. return (dx <= -2 || 2 <= dx || dy <= -2 || 2 <= dy);
  1053. }
  1054. void LLToolPie::render()
  1055. {
  1056. return;
  1057. }
  1058. static void handle_click_action_play()
  1059. {
  1060. LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
  1061. if (!parcel) return;
  1062. LLViewerMediaImpl::EMediaStatus status = LLViewerParcelMedia::getStatus();
  1063. switch(status)
  1064. {
  1065. case LLViewerMediaImpl::MEDIA_PLAYING:
  1066. LLViewerParcelMedia::pause();
  1067. break;
  1068. case LLViewerMediaImpl::MEDIA_PAUSED:
  1069. LLViewerParcelMedia::start();
  1070. break;
  1071. default:
  1072. LLViewerParcelMedia::play(parcel);
  1073. break;
  1074. }
  1075. }
  1076. bool LLToolPie::handleMediaClick(const LLPickInfo& pick)
  1077. {
  1078. //FIXME: how do we handle object in different parcel than us?
  1079. LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
  1080. LLPointer<LLViewerObject> objectp = pick.getObject();
  1081. if (!parcel ||
  1082. objectp.isNull() ||
  1083. pick.mObjectFace < 0 || 
  1084. pick.mObjectFace >= objectp->getNumTEs()) 
  1085. {
  1086. LLViewerMediaFocus::getInstance()->clearFocus();
  1087. return false;
  1088. }
  1089. // Does this face have media?
  1090. const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace);
  1091. if(!tep)
  1092. return false;
  1093. LLMediaEntry* mep = (tep->hasMedia()) ? tep->getMediaData() : NULL;
  1094. if(!mep)
  1095. return false;
  1096. viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
  1097. if (gSavedSettings.getBOOL("MediaOnAPrimUI"))
  1098. {
  1099. if (!LLViewerMediaFocus::getInstance()->isFocusedOnFace(pick.getObject(), pick.mObjectFace) || media_impl.isNull())
  1100. {
  1101. // It's okay to give this a null impl
  1102. LLViewerMediaFocus::getInstance()->setFocusFace(pick.getObject(), pick.mObjectFace, media_impl, pick.mNormal);
  1103. }
  1104. else
  1105. {
  1106. // Make sure keyboard focus is set to the media focus object.
  1107. gFocusMgr.setKeyboardFocus(LLViewerMediaFocus::getInstance());
  1108. media_impl->mouseDown(pick.mUVCoords, gKeyboard->currentMask(TRUE));
  1109. mMediaMouseCaptureID = mep->getMediaID();
  1110. setMouseCapture(TRUE);  // This object will send a mouse-up to the media when it loses capture.
  1111. }
  1112. return true;
  1113. }
  1114. LLViewerMediaFocus::getInstance()->clearFocus();
  1115. return false;
  1116. }
  1117. bool LLToolPie::handleMediaHover(const LLPickInfo& pick)
  1118. {
  1119. //FIXME: how do we handle object in different parcel than us?
  1120. LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
  1121. if (!parcel) return false;
  1122. LLPointer<LLViewerObject> objectp = pick.getObject();
  1123. // Early out cases.  Must clear media hover. 
  1124. // did not hit an object or did not hit a valid face
  1125. if ( objectp.isNull() ||
  1126. pick.mObjectFace < 0 || 
  1127. pick.mObjectFace >= objectp->getNumTEs() )
  1128. {
  1129. LLViewerMediaFocus::getInstance()->clearHover();
  1130. return false;
  1131. }
  1132. // Does this face have media?
  1133. const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace);
  1134. if(!tep)
  1135. return false;
  1136. const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL;
  1137. if (mep
  1138. && gSavedSettings.getBOOL("MediaOnAPrimUI"))
  1139. {
  1140. viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
  1141. if(media_impl.notNull())
  1142. {
  1143. // Update media hover object
  1144. if (!LLViewerMediaFocus::getInstance()->isHoveringOverFace(objectp, pick.mObjectFace))
  1145. {
  1146. LLViewerMediaFocus::getInstance()->setHoverFace(objectp, pick.mObjectFace, media_impl, pick.mNormal);
  1147. }
  1148. // If this is the focused media face, send mouse move events.
  1149. if (LLViewerMediaFocus::getInstance()->isFocusedOnFace(objectp, pick.mObjectFace))
  1150. {
  1151. media_impl->mouseMove(pick.mUVCoords, gKeyboard->currentMask(TRUE));
  1152. gViewerWindow->setCursor(media_impl->getLastSetCursor());
  1153. }
  1154. else
  1155. {
  1156. // This is not the focused face -- set the default cursor.
  1157. gViewerWindow->setCursor(UI_CURSOR_ARROW);
  1158. }
  1159. return true;
  1160. }
  1161. }
  1162. // In all other cases, clear media hover.
  1163. LLViewerMediaFocus::getInstance()->clearHover();
  1164. return false;
  1165. }
  1166. bool LLToolPie::handleMediaMouseUp()
  1167. {
  1168. bool result = false;
  1169. if(mMediaMouseCaptureID.notNull())
  1170. {
  1171. // Face media needs to know the mouse went up.
  1172. viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mMediaMouseCaptureID);
  1173. if(media_impl)
  1174. {
  1175. // This will send a mouseUp event to the plugin using the last known mouse coordinate (from a mouseDown or mouseMove), which is what we want.
  1176. media_impl->onMouseCaptureLost();
  1177. }
  1178. mMediaMouseCaptureID.setNull();
  1179. setMouseCapture(FALSE);
  1180. result = true;
  1181. }
  1182. return result;
  1183. }
  1184. static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp)
  1185. {
  1186. //FIXME: how do we handle object in different parcel than us?
  1187. LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
  1188. if (!parcel) return;
  1189. // did we hit an object?
  1190. if (objectp.isNull()) return;
  1191. // did we hit a valid face on the object?
  1192. S32 face = LLToolPie::getInstance()->getPick().mObjectFace;
  1193. if( face < 0 || face >= objectp->getNumTEs() ) return;
  1194. // is media playing on this face?
  1195. if (LLViewerMedia::getMediaImplFromTextureID(objectp->getTE(face)->getID()) != NULL)
  1196. {
  1197. handle_click_action_play();
  1198. return;
  1199. }
  1200. std::string media_url = std::string ( parcel->getMediaURL () );
  1201. std::string media_type = std::string ( parcel->getMediaType() );
  1202. LLStringUtil::trim(media_url);
  1203. LLWeb::loadURL(media_url);
  1204. }
  1205. static ECursorType cursor_from_parcel_media(U8 click_action)
  1206. {
  1207. // HACK: This is directly referencing an impl name.  BAD!
  1208. // This can be removed when we have a truly generic media browser that only 
  1209. // builds an impl based on the type of url it is passed.
  1210. //FIXME: how do we handle object in different parcel than us?
  1211. ECursorType open_cursor = UI_CURSOR_ARROW;
  1212. LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
  1213. if (!parcel) return open_cursor;
  1214. std::string media_url = std::string ( parcel->getMediaURL () );
  1215. std::string media_type = std::string ( parcel->getMediaType() );
  1216. LLStringUtil::trim(media_url);
  1217. open_cursor = UI_CURSOR_TOOLMEDIAOPEN;
  1218. LLViewerMediaImpl::EMediaStatus status = LLViewerParcelMedia::getStatus();
  1219. switch(status)
  1220. {
  1221. case LLViewerMediaImpl::MEDIA_PLAYING:
  1222. return click_action == CLICK_ACTION_PLAY ? UI_CURSOR_TOOLPAUSE : open_cursor;
  1223. default:
  1224. return UI_CURSOR_TOOLPLAY;
  1225. }
  1226. }
  1227. // True if we handled the event.
  1228. BOOL LLToolPie::pickRightMouseDownCallback()
  1229. {
  1230. S32 x = mPick.mMousePt.mX;
  1231. S32 y = mPick.mMousePt.mY;
  1232. MASK mask = mPick.mKeyMask;
  1233. if (mPick.mPickType != LLPickInfo::PICK_LAND)
  1234. {
  1235. LLViewerParcelMgr::getInstance()->deselectLand();
  1236. }
  1237. // didn't click in any UI object, so must have clicked in the world
  1238. LLViewerObject *object = mPick.getObject();
  1239. LLViewerObject *parent = NULL;
  1240. if(object)
  1241. parent = object->getRootEdit();
  1242. // Can't ignore children here.
  1243. LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE);
  1244. // Spawn pie menu
  1245. if (mPick.mPickType == LLPickInfo::PICK_LAND)
  1246. {
  1247. LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstance()->selectParcelAt( mPick.mPosGlobal );
  1248. gMenuHolder->setParcelSelection(selection);
  1249. gMenuLand->show(x, y);
  1250. showVisualContextMenuEffect();
  1251. }
  1252. else if (mPick.mObjectID == gAgent.getID() )
  1253. {
  1254. if(!gMenuAvatarSelf) 
  1255. {
  1256. //either at very early startup stage or at late quitting stage,
  1257. //this event is ignored.
  1258. return TRUE ;
  1259. }
  1260. gMenuAvatarSelf->show(x, y);
  1261. }
  1262. else if (object)
  1263. {
  1264. gMenuHolder->setObjectSelection(LLSelectMgr::getInstance()->getSelection());
  1265. bool is_other_attachment = (object->isAttachment() && !object->isHUDAttachment() && !object->permYouOwner());
  1266. if (object->isAvatar() 
  1267. || is_other_attachment)
  1268. {
  1269. // Find the attachment's avatar
  1270. while( object && object->isAttachment())
  1271. {
  1272. object = (LLViewerObject*)object->getParent();
  1273. llassert(object);
  1274. }
  1275. if (!object)
  1276. {
  1277. return TRUE; // unexpected, but escape
  1278. }
  1279. // Object is an avatar, so check for mute by id.
  1280. LLVOAvatar* avatar = (LLVOAvatar*)object;
  1281. std::string name = avatar->getFullname();
  1282. std::string mute_msg;
  1283. if (LLMuteList::getInstance()->isMuted(avatar->getID(), avatar->getFullname()))
  1284. {
  1285. mute_msg = LLTrans::getString("UnmuteAvatar");
  1286. }
  1287. else
  1288. {
  1289. mute_msg = LLTrans::getString("MuteAvatar");
  1290. }
  1291. if (is_other_attachment)
  1292. {
  1293. gMenuAttachmentOther->getChild<LLUICtrl>("Avatar Mute")->setValue(mute_msg);
  1294. gMenuAttachmentOther->show(x, y);
  1295. }
  1296. else
  1297. {
  1298. gMenuAvatarOther->getChild<LLUICtrl>("Avatar Mute")->setValue(mute_msg);
  1299. gMenuAvatarOther->show(x, y);
  1300. }
  1301. }
  1302. else if (object->isAttachment())
  1303. {
  1304. gMenuAttachmentSelf->show(x, y);
  1305. }
  1306. else
  1307. {
  1308. // BUG: What about chatting child objects?
  1309. std::string name;
  1310. LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
  1311. if (node)
  1312. {
  1313. name = node->mName;
  1314. }
  1315. std::string mute_msg;
  1316. if (LLMuteList::getInstance()->isMuted(object->getID(), name))
  1317. {
  1318. mute_msg = LLTrans::getString("UnmuteObject");
  1319. }
  1320. else
  1321. {
  1322. mute_msg = LLTrans::getString("MuteObject2");
  1323. }
  1324. gMenuHolder->childSetText("Object Mute", mute_msg);
  1325. gMenuObject->show(x, y);
  1326. showVisualContextMenuEffect();
  1327. }
  1328. }
  1329. LLTool::handleRightMouseDown(x, y, mask);
  1330. // We handled the event.
  1331. return TRUE;
  1332. }
  1333. void LLToolPie::showVisualContextMenuEffect()
  1334. {
  1335. // VEFFECT: ShowPie
  1336. LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_SPHERE, TRUE);
  1337. effectp->setPositionGlobal(mPick.mPosGlobal);
  1338. effectp->setColor(LLColor4U(gAgent.getEffectColor()));
  1339. effectp->setDuration(0.25f);
  1340. }