PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llnavigationbar.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 700 lines | 497 code | 95 blank | 108 comment | 64 complexity | 5e24d8d727b8d6c88e5770a584bcc529 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llnavigationbar.cpp
  3. * @brief Navigation bar implementation
  4. *
  5. * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "llviewerprecompiledheaders.h"
  27. #include "llnavigationbar.h"
  28. #include "v2math.h"
  29. #include "llregionhandle.h"
  30. #include "llfloaterreg.h"
  31. #include "llfocusmgr.h"
  32. #include "lliconctrl.h"
  33. #include "llmenugl.h"
  34. #include "llagent.h"
  35. #include "llviewerregion.h"
  36. #include "lllandmarkactions.h"
  37. #include "lllocationhistory.h"
  38. #include "lllocationinputctrl.h"
  39. #include "llpaneltopinfobar.h"
  40. #include "llteleporthistory.h"
  41. #include "llsearchcombobox.h"
  42. #include "llslurl.h"
  43. #include "llurlregistry.h"
  44. #include "llurldispatcher.h"
  45. #include "llviewerinventory.h"
  46. #include "llviewermenu.h"
  47. #include "llviewerparcelmgr.h"
  48. #include "llworldmapmessage.h"
  49. #include "llappviewer.h"
  50. #include "llviewercontrol.h"
  51. #include "llweb.h"
  52. #include "llhints.h"
  53. #include "llinventorymodel.h"
  54. #include "lllandmarkactions.h"
  55. #include "llfavoritesbar.h"
  56. #include "llagentui.h"
  57. #include <boost/regex.hpp>
  58. //-- LLTeleportHistoryMenuItem -----------------------------------------------
  59. /**
  60. * Item look varies depending on the type (backward/current/forward).
  61. */
  62. class LLTeleportHistoryMenuItem : public LLMenuItemCallGL
  63. {
  64. public:
  65. typedef enum e_item_type
  66. {
  67. TYPE_BACKWARD,
  68. TYPE_CURRENT,
  69. TYPE_FORWARD,
  70. } EType;
  71. struct Params : public LLInitParam::Block<Params, LLMenuItemCallGL::Params>
  72. {
  73. Mandatory<EType> item_type;
  74. Optional<const LLFontGL*> back_item_font,
  75. current_item_font,
  76. forward_item_font;
  77. Optional<std::string> back_item_image,
  78. forward_item_image;
  79. Optional<S32> image_hpad,
  80. image_vpad;
  81. Params()
  82. : item_type(),
  83. back_item_font("back_item_font"),
  84. current_item_font("current_item_font"),
  85. forward_item_font("forward_item_font"),
  86. back_item_image("back_item_image"),
  87. forward_item_image("forward_item_image"),
  88. image_hpad("image_hpad"),
  89. image_vpad("image_vpad")
  90. {}
  91. };
  92. /*virtual*/ void draw();
  93. /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
  94. /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
  95. private:
  96. LLTeleportHistoryMenuItem(const Params&);
  97. friend class LLUICtrlFactory;
  98. static const S32 ICON_WIDTH = 16;
  99. static const S32 ICON_HEIGHT = 16;
  100. LLIconCtrl* mArrowIcon;
  101. };
  102. static LLDefaultChildRegistry::Register<LLTeleportHistoryMenuItem> r("teleport_history_menu_item");
  103. LLTeleportHistoryMenuItem::LLTeleportHistoryMenuItem(const Params& p)
  104. : LLMenuItemCallGL(p),
  105. mArrowIcon(NULL)
  106. {
  107. // Set appearance depending on the item type.
  108. if (p.item_type == TYPE_BACKWARD)
  109. {
  110. setFont( p.back_item_font );
  111. }
  112. else if (p.item_type == TYPE_CURRENT)
  113. {
  114. setFont( p.current_item_font );
  115. }
  116. else
  117. {
  118. setFont( p.forward_item_font );
  119. }
  120. LLIconCtrl::Params icon_params;
  121. icon_params.name("icon");
  122. LLRect rect(0, ICON_HEIGHT, ICON_WIDTH, 0);
  123. rect.translate( p.image_hpad, p.image_vpad );
  124. icon_params.rect( rect );
  125. icon_params.mouse_opaque(false);
  126. icon_params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
  127. icon_params.visible(false);
  128. mArrowIcon = LLUICtrlFactory::create<LLIconCtrl> (icon_params);
  129. // no image for the current item
  130. if (p.item_type == TYPE_BACKWARD)
  131. mArrowIcon->setValue( p.back_item_image() );
  132. else if (p.item_type == TYPE_FORWARD)
  133. mArrowIcon->setValue( p.forward_item_image() );
  134. addChild(mArrowIcon);
  135. }
  136. void LLTeleportHistoryMenuItem::draw()
  137. {
  138. // Draw menu item itself.
  139. LLMenuItemCallGL::draw();
  140. // Draw children if any. *TODO: move this to LLMenuItemGL?
  141. LLUICtrl::draw();
  142. }
  143. void LLTeleportHistoryMenuItem::onMouseEnter(S32 x, S32 y, MASK mask)
  144. {
  145. mArrowIcon->setVisible(TRUE);
  146. }
  147. void LLTeleportHistoryMenuItem::onMouseLeave(S32 x, S32 y, MASK mask)
  148. {
  149. mArrowIcon->setVisible(FALSE);
  150. }
  151. static LLDefaultChildRegistry::Register<LLPullButton> menu_button("pull_button");
  152. LLPullButton::LLPullButton(const LLPullButton::Params& params) :
  153. LLButton(params)
  154. {
  155. setDirectionFromName(params.direction);
  156. }
  157. boost::signals2::connection LLPullButton::setClickDraggingCallback(const commit_signal_t::slot_type& cb)
  158. {
  159. return mClickDraggingSignal.connect(cb);
  160. }
  161. /*virtual*/
  162. void LLPullButton::onMouseLeave(S32 x, S32 y, MASK mask)
  163. {
  164. LLButton::onMouseLeave(x, y, mask);
  165. if (mMouseDownTimer.getStarted()) //an user have done a mouse down, if the timer started. see LLButton::handleMouseDown for details
  166. {
  167. const LLVector2 cursor_direction = LLVector2(F32(x), F32(y)) - mLastMouseDown;
  168. /* For now cursor_direction points to the direction of mouse movement
  169. * Need to decide whether should we fire a signal.
  170. * We fire if angle between mDraggingDirection and cursor_direction is less that 45 degree
  171. * Note:
  172. * 0.5 * F_PI_BY_TWO equals to PI/4 radian that equals to angle of 45 degrees
  173. */
  174. if (angle_between(mDraggingDirection, cursor_direction) < 0.5 * F_PI_BY_TWO)//call if angle < pi/4
  175. {
  176. mClickDraggingSignal(this, LLSD());
  177. }
  178. }
  179. }
  180. /*virtual*/
  181. BOOL LLPullButton::handleMouseDown(S32 x, S32 y, MASK mask)
  182. {
  183. BOOL handled = LLButton::handleMouseDown(x, y, mask);
  184. if (handled)
  185. {
  186. //if mouse down was handled by button,
  187. //capture mouse position to calculate the direction of mouse move after mouseLeave event
  188. mLastMouseDown.set(F32(x), F32(y));
  189. }
  190. return handled;
  191. }
  192. /*virtual*/
  193. BOOL LLPullButton::handleMouseUp(S32 x, S32 y, MASK mask)
  194. {
  195. // reset data to get ready for next circle
  196. mLastMouseDown.clear();
  197. return LLButton::handleMouseUp(x, y, mask);
  198. }
  199. /**
  200. * this function is setting up dragging direction vector.
  201. * Last one is just unit vector. It points to direction of mouse drag that we need to handle
  202. */
  203. void LLPullButton::setDirectionFromName(const std::string& name)
  204. {
  205. if (name == "left")
  206. {
  207. mDraggingDirection.set(F32(-1), F32(0));
  208. }
  209. else if (name == "right")
  210. {
  211. mDraggingDirection.set(F32(0), F32(1));
  212. }
  213. else if (name == "down")
  214. {
  215. mDraggingDirection.set(F32(0), F32(-1));
  216. }
  217. else if (name == "up")
  218. {
  219. mDraggingDirection.set(F32(0), F32(1));
  220. }
  221. }
  222. //-- LNavigationBar ----------------------------------------------------------
  223. /*
  224. TODO:
  225. - Load navbar height from saved settings (as it's done for status bar) or think of a better way.
  226. */
  227. LLNavigationBar::LLNavigationBar()
  228. : mTeleportHistoryMenu(NULL),
  229. mBtnBack(NULL),
  230. mBtnForward(NULL),
  231. mBtnHome(NULL),
  232. mCmbLocation(NULL),
  233. mPurgeTPHistoryItems(false),
  234. mSaveToLocationHistory(false)
  235. {
  236. buildFromFile( "panel_navigation_bar.xml");
  237. // set a listener function for LoginComplete event
  238. LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLNavigationBar::handleLoginComplete, this));
  239. }
  240. LLNavigationBar::~LLNavigationBar()
  241. {
  242. mTeleportFinishConnection.disconnect();
  243. mTeleportFailedConnection.disconnect();
  244. }
  245. BOOL LLNavigationBar::postBuild()
  246. {
  247. mBtnBack = getChild<LLPullButton>("back_btn");
  248. mBtnForward = getChild<LLPullButton>("forward_btn");
  249. mBtnHome = getChild<LLButton>("home_btn");
  250. mCmbLocation= getChild<LLLocationInputCtrl>("location_combo");
  251. mBtnBack->setEnabled(FALSE);
  252. mBtnBack->setClickedCallback(boost::bind(&LLNavigationBar::onBackButtonClicked, this));
  253. mBtnBack->setHeldDownCallback(boost::bind(&LLNavigationBar::onBackOrForwardButtonHeldDown, this,_1, _2));
  254. mBtnBack->setClickDraggingCallback(boost::bind(&LLNavigationBar::showTeleportHistoryMenu, this,_1));
  255. mBtnForward->setEnabled(FALSE);
  256. mBtnForward->setClickedCallback(boost::bind(&LLNavigationBar::onForwardButtonClicked, this));
  257. mBtnForward->setHeldDownCallback(boost::bind(&LLNavigationBar::onBackOrForwardButtonHeldDown, this, _1, _2));
  258. mBtnForward->setClickDraggingCallback(boost::bind(&LLNavigationBar::showTeleportHistoryMenu, this,_1));
  259. mBtnHome->setClickedCallback(boost::bind(&LLNavigationBar::onHomeButtonClicked, this));
  260. mCmbLocation->setCommitCallback(boost::bind(&LLNavigationBar::onLocationSelection, this));
  261. mTeleportFinishConnection = LLViewerParcelMgr::getInstance()->
  262. setTeleportFinishedCallback(boost::bind(&LLNavigationBar::onTeleportFinished, this, _1));
  263. mTeleportFailedConnection = LLViewerParcelMgr::getInstance()->
  264. setTeleportFailedCallback(boost::bind(&LLNavigationBar::onTeleportFailed, this));
  265. mDefaultNbRect = getRect();
  266. mDefaultFpRect = getChild<LLFavoritesBarCtrl>("favorite")->getRect();
  267. // we'll be notified on teleport history changes
  268. LLTeleportHistory::getInstance()->setHistoryChangedCallback(
  269. boost::bind(&LLNavigationBar::onTeleportHistoryChanged, this));
  270. LLHints::registerHintTarget("nav_bar", getHandle());
  271. return TRUE;
  272. }
  273. void LLNavigationBar::setVisible(BOOL visible)
  274. {
  275. // change visibility of grandparent layout_panel to animate in and out
  276. if (getParent())
  277. {
  278. //to avoid some mysterious bugs like EXT-3352, at least try to log an incorrect parent to ping about a problem.
  279. if(getParent()->getName() != "nav_bar_container")
  280. {
  281. LL_WARNS("LLNavigationBar")<<"NavigationBar has an unknown name of the parent: "<<getParent()->getName()<< LL_ENDL;
  282. }
  283. getParent()->setVisible(visible);
  284. }
  285. }
  286. void LLNavigationBar::draw()
  287. {
  288. if(mPurgeTPHistoryItems)
  289. {
  290. LLTeleportHistory::getInstance()->purgeItems();
  291. mPurgeTPHistoryItems = false;
  292. }
  293. if (isBackgroundVisible())
  294. {
  295. static LLUICachedControl<S32> drop_shadow_floater ("DropShadowFloater", 0);
  296. static LLUIColor color_drop_shadow = LLUIColorTable::instance().getColor("ColorDropShadow");
  297. gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0,
  298. color_drop_shadow, drop_shadow_floater );
  299. }
  300. LLPanel::draw();
  301. }
  302. BOOL LLNavigationBar::handleRightMouseDown(S32 x, S32 y, MASK mask)
  303. {
  304. BOOL handled = childrenHandleRightMouseDown( x, y, mask) != NULL;
  305. if(!handled && !gMenuHolder->hasVisibleMenu())
  306. {
  307. show_navbar_context_menu(this,x,y);
  308. handled = true;
  309. }
  310. return handled;
  311. }
  312. void LLNavigationBar::onBackButtonClicked()
  313. {
  314. LLTeleportHistory::getInstance()->goBack();
  315. }
  316. void LLNavigationBar::onBackOrForwardButtonHeldDown(LLUICtrl* ctrl, const LLSD& param)
  317. {
  318. if (param["count"].asInteger() == 0)
  319. showTeleportHistoryMenu(ctrl);
  320. }
  321. void LLNavigationBar::onForwardButtonClicked()
  322. {
  323. LLTeleportHistory::getInstance()->goForward();
  324. }
  325. void LLNavigationBar::onHomeButtonClicked()
  326. {
  327. gAgent.teleportHome();
  328. }
  329. void LLNavigationBar::onTeleportHistoryMenuItemClicked(const LLSD& userdata)
  330. {
  331. int idx = userdata.asInteger();
  332. LLTeleportHistory::getInstance()->goToItem(idx);
  333. }
  334. // This is called when user presses enter in the location input
  335. // or selects a location from the typed locations dropdown.
  336. void LLNavigationBar::onLocationSelection()
  337. {
  338. std::string typed_location = mCmbLocation->getSimple();
  339. LLStringUtil::trim(typed_location);
  340. // Will not teleport to empty location.
  341. if (typed_location.empty())
  342. return;
  343. //get selected item from combobox item
  344. LLSD value = mCmbLocation->getSelectedValue();
  345. if(value.isUndefined() && !mCmbLocation->getTextEntry()->isDirty())
  346. {
  347. // At this point we know that: there is no selected item in list and text field has NOT been changed
  348. // So there is no sense to try to change the location
  349. return;
  350. }
  351. /* since navbar list support autocompletion it contains several types of item: landmark, teleport hystory item,
  352. * typed by user slurl or region name. Let's find out which type of item the user has selected
  353. * to make decision about adding this location into typed history. see mSaveToLocationHistory
  354. * Note:
  355. * Only TYPED_REGION_SLURL item will be added into LLLocationHistory
  356. */
  357. if(value.has("item_type"))
  358. {
  359. switch(value["item_type"].asInteger())
  360. {
  361. case LANDMARK:
  362. if(value.has("AssetUUID"))
  363. {
  364. gAgent.teleportViaLandmark( LLUUID(value["AssetUUID"].asString()));
  365. return;
  366. }
  367. else
  368. {
  369. LLInventoryModel::item_array_t landmark_items =
  370. LLLandmarkActions::fetchLandmarksByName(typed_location,
  371. FALSE);
  372. if (!landmark_items.empty())
  373. {
  374. gAgent.teleportViaLandmark( landmark_items[0]->getAssetUUID());
  375. return;
  376. }
  377. }
  378. break;
  379. case TELEPORT_HISTORY:
  380. //in case of teleport item was selected, teleport by position too.
  381. case TYPED_REGION_SLURL:
  382. if(value.has("global_pos"))
  383. {
  384. gAgent.teleportViaLocation(LLVector3d(value["global_pos"]));
  385. return;
  386. }
  387. break;
  388. default:
  389. break;
  390. }
  391. }
  392. //Let's parse slurl or region name
  393. std::string region_name;
  394. LLVector3 local_coords(128, 128, 0);
  395. // Is the typed location a SLURL?
  396. LLSLURL slurl = LLSLURL(typed_location);
  397. if (slurl.getType() == LLSLURL::LOCATION)
  398. {
  399. region_name = slurl.getRegion();
  400. local_coords = slurl.getPosition();
  401. }
  402. else if(!slurl.isValid())
  403. {
  404. // we have to do this check after previous, because LLUrlRegistry contains handlers for slurl too
  405. // but we need to know whether typed_location is a simple http url.
  406. if (LLUrlRegistry::instance().isUrl(typed_location))
  407. {
  408. // display http:// URLs in the media browser, or
  409. // anything else is sent to the search floater
  410. LLWeb::loadURL(typed_location);
  411. return;
  412. }
  413. else
  414. {
  415. // assume that an user has typed the {region name} or possible {region_name, parcel}
  416. region_name = typed_location.substr(0,typed_location.find(','));
  417. }
  418. }
  419. else
  420. {
  421. // was an app slurl, home, whatever. Bail
  422. return;
  423. }
  424. // Resolve the region name to its global coordinates.
  425. // If resolution succeeds we'll teleport.
  426. LLWorldMapMessage::url_callback_t cb = boost::bind(
  427. &LLNavigationBar::onRegionNameResponse, this,
  428. typed_location, region_name, local_coords, _1, _2, _3, _4);
  429. mSaveToLocationHistory = true;
  430. LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name, cb, std::string("unused"), false);
  431. }
  432. void LLNavigationBar::onTeleportFailed()
  433. {
  434. mSaveToLocationHistory = false;
  435. }
  436. void LLNavigationBar::onTeleportFinished(const LLVector3d& global_agent_pos)
  437. {
  438. if (!mSaveToLocationHistory)
  439. return;
  440. LLLocationHistory* lh = LLLocationHistory::getInstance();
  441. //TODO*: do we need convert slurl into readable format?
  442. std::string location;
  443. /*NOTE:
  444. * We can't use gAgent.getPositionAgent() in case of local teleport to build location.
  445. * At this moment gAgent.getPositionAgent() contains previous coordinates.
  446. * according to EXT-65 agent position is being reseted on each frame.
  447. */
  448. LLAgentUI::buildLocationString(location, LLAgentUI::LOCATION_FORMAT_NO_MATURITY,
  449. gAgent.getPosAgentFromGlobal(global_agent_pos));
  450. std::string tooltip (LLSLURL(gAgent.getRegion()->getName(), global_agent_pos).getSLURLString());
  451. LLLocationHistoryItem item (location,
  452. global_agent_pos, tooltip,TYPED_REGION_SLURL);// we can add into history only TYPED location
  453. //Touch it, if it is at list already, add new location otherwise
  454. if ( !lh->touchItem(item) ) {
  455. lh->addItem(item);
  456. }
  457. lh->save();
  458. mSaveToLocationHistory = false;
  459. }
  460. void LLNavigationBar::onTeleportHistoryChanged()
  461. {
  462. // Update navigation controls.
  463. LLTeleportHistory* h = LLTeleportHistory::getInstance();
  464. int cur_item = h->getCurrentItemIndex();
  465. mBtnBack->setEnabled(cur_item > 0);
  466. mBtnForward->setEnabled(cur_item < ((int)h->getItems().size() - 1));
  467. }
  468. void LLNavigationBar::rebuildTeleportHistoryMenu()
  469. {
  470. // Has the pop-up menu been built?
  471. if (mTeleportHistoryMenu)
  472. {
  473. // Clear it.
  474. mTeleportHistoryMenu->empty();
  475. }
  476. else
  477. {
  478. // Create it.
  479. LLMenuGL::Params menu_p;
  480. menu_p.name("popup");
  481. menu_p.can_tear_off(false);
  482. menu_p.visible(false);
  483. menu_p.bg_visible(true);
  484. menu_p.scrollable(true);
  485. mTeleportHistoryMenu = LLUICtrlFactory::create<LLMenuGL>(menu_p);
  486. addChild(mTeleportHistoryMenu);
  487. }
  488. // Populate the menu with teleport history items.
  489. LLTeleportHistory* hist = LLTeleportHistory::getInstance();
  490. const LLTeleportHistory::slurl_list_t& hist_items = hist->getItems();
  491. int cur_item = hist->getCurrentItemIndex();
  492. // Items will be shown in the reverse order, just like in Firefox.
  493. for (int i = (int)hist_items.size()-1; i >= 0; i--)
  494. {
  495. LLTeleportHistoryMenuItem::EType type;
  496. if (i < cur_item)
  497. type = LLTeleportHistoryMenuItem::TYPE_BACKWARD;
  498. else if (i > cur_item)
  499. type = LLTeleportHistoryMenuItem::TYPE_FORWARD;
  500. else
  501. type = LLTeleportHistoryMenuItem::TYPE_CURRENT;
  502. LLTeleportHistoryMenuItem::Params item_params;
  503. item_params.label = item_params.name = hist_items[i].mTitle;
  504. item_params.item_type = type;
  505. item_params.on_click.function(boost::bind(&LLNavigationBar::onTeleportHistoryMenuItemClicked, this, i));
  506. LLTeleportHistoryMenuItem* new_itemp = LLUICtrlFactory::create<LLTeleportHistoryMenuItem>(item_params);
  507. //new_itemp->setFont()
  508. mTeleportHistoryMenu->addChild(new_itemp);
  509. }
  510. }
  511. void LLNavigationBar::onRegionNameResponse(
  512. std::string typed_location,
  513. std::string region_name,
  514. LLVector3 local_coords,
  515. U64 region_handle, const std::string& url, const LLUUID& snapshot_id, bool teleport)
  516. {
  517. // Invalid location?
  518. if (region_handle)
  519. {
  520. // Teleport to the location.
  521. LLVector3d region_pos = from_region_handle(region_handle);
  522. LLVector3d global_pos = region_pos + (LLVector3d) local_coords;
  523. llinfos << "Teleporting to: " << LLSLURL(region_name, global_pos).getSLURLString() << llendl;
  524. gAgent.teleportViaLocation(global_pos);
  525. }
  526. else if (gSavedSettings.getBOOL("SearchFromAddressBar"))
  527. {
  528. invokeSearch(typed_location);
  529. }
  530. }
  531. void LLNavigationBar::showTeleportHistoryMenu(LLUICtrl* btn_ctrl)
  532. {
  533. // Don't show the popup if teleport history is empty.
  534. if (LLTeleportHistory::getInstance()->isEmpty())
  535. {
  536. lldebugs << "Teleport history is empty, will not show the menu." << llendl;
  537. return;
  538. }
  539. rebuildTeleportHistoryMenu();
  540. if (mTeleportHistoryMenu == NULL)
  541. return;
  542. mTeleportHistoryMenu->updateParent(LLMenuGL::sMenuContainer);
  543. const S32 MENU_SPAWN_PAD = -1;
  544. LLMenuGL::showPopup(btn_ctrl, mTeleportHistoryMenu, 0, MENU_SPAWN_PAD);
  545. LLButton* nav_button = dynamic_cast<LLButton*>(btn_ctrl);
  546. if(nav_button)
  547. {
  548. if(mHistoryMenuConnection.connected())
  549. {
  550. LL_WARNS("Navgationbar")<<"mHistoryMenuConnection should be disconnected at this moment."<<LL_ENDL;
  551. mHistoryMenuConnection.disconnect();
  552. }
  553. mHistoryMenuConnection = gMenuHolder->setMouseUpCallback(boost::bind(&LLNavigationBar::onNavigationButtonHeldUp, this, nav_button));
  554. // pressed state will be update after mouseUp in onBackOrForwardButtonHeldUp();
  555. nav_button->setForcePressedState(true);
  556. }
  557. // *HACK pass the mouse capturing to the drop-down menu
  558. // it need to let menu handle mouseup event
  559. gFocusMgr.setMouseCapture(gMenuHolder);
  560. }
  561. /**
  562. * Taking into account the HACK above, this callback-function is responsible for correct handling of mouseUp event in case of holding-down the navigation buttons..
  563. * We need to process this case separately to update a pressed state of navigation button.
  564. */
  565. void LLNavigationBar::onNavigationButtonHeldUp(LLButton* nav_button)
  566. {
  567. if(nav_button)
  568. {
  569. nav_button->setForcePressedState(false);
  570. }
  571. if(gFocusMgr.getMouseCapture() == gMenuHolder)
  572. {
  573. // we had passed mouseCapture in showTeleportHistoryMenu()
  574. // now we MUST release mouseCapture to continue a proper mouseevent workflow.
  575. gFocusMgr.setMouseCapture(NULL);
  576. }
  577. //gMenuHolder is using to display bunch of menus. Disconnect signal to avoid unnecessary calls.
  578. mHistoryMenuConnection.disconnect();
  579. }
  580. void LLNavigationBar::handleLoginComplete()
  581. {
  582. LLTeleportHistory::getInstance()->handleLoginComplete();
  583. LLPanelTopInfoBar::instance().handleLoginComplete();
  584. mCmbLocation->handleLoginComplete();
  585. }
  586. void LLNavigationBar::invokeSearch(std::string search_text)
  587. {
  588. LLFloaterReg::showInstance("search", LLSD().with("category", "all").with("query", LLSD(search_text)));
  589. }
  590. void LLNavigationBar::clearHistoryCache()
  591. {
  592. mCmbLocation->removeall();
  593. LLLocationHistory* lh = LLLocationHistory::getInstance();
  594. lh->removeItems();
  595. lh->save();
  596. mPurgeTPHistoryItems= true;
  597. }
  598. int LLNavigationBar::getDefNavBarHeight()
  599. {
  600. return mDefaultNbRect.getHeight();
  601. }
  602. int LLNavigationBar::getDefFavBarHeight()
  603. {
  604. return mDefaultFpRect.getHeight();
  605. }