lltoolbar.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. /**
  2. * @file lltoolbar.cpp
  3. * @author James Cook, Richard Nelson
  4. * @brief Large friendly buttons at bottom of screen.
  5. *
  6. * $LicenseInfo:firstyear=2002&license=viewergpl$
  7. *
  8. * Copyright (c) 2002-2009, Linden Research, Inc.
  9. *
  10. * Second Life Viewer Source Code
  11. * The source code in this file ("Source Code") is provided by Linden Lab
  12. * to you under the terms of the GNU General Public License, version 2.0
  13. * ("GPL"), unless you have obtained a separate licensing agreement
  14. * ("Other License"), formally executed by you and Linden Lab. Terms of
  15. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  16. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  17. *
  18. * There are special exceptions to the terms and conditions of the GPL as
  19. * it is applied to this Source Code. View the full text of the exception
  20. * in the file doc/FLOSS-exception.txt in this software distribution, or
  21. * online at
  22. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  23. *
  24. * By copying, modifying or distributing this software, you acknowledge
  25. * that you have read and understood your obligations described above,
  26. * and agree to abide by those obligations.
  27. *
  28. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  29. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  30. * COMPLETENESS OR PERFORMANCE.
  31. * $/LicenseInfo$
  32. */
  33. #include "llviewerprecompiledheaders.h"
  34. #include "lltoolbar.h"
  35. #include "imageids.h"
  36. #include "llbutton.h"
  37. #include "llparcel.h"
  38. #include "lluictrlfactory.h"
  39. #include "llagent.h"
  40. #include "llfirstuse.h"
  41. #include "llfloaterchatterbox.h"
  42. #include "llfloaterfriends.h"
  43. #include "llfloatergroups.h"
  44. #include "llfloaterinventory.h"
  45. #include "llfloaterminimap.h"
  46. #include "hbfloatersearch.h"
  47. #include "hbfloaterradar.h"
  48. #include "llfloatersnapshot.h"
  49. #include "llfloaterworldmap.h"
  50. //MK
  51. #include "mkrlinterface.h"
  52. //mk
  53. #include "lltooldraganddrop.h"
  54. #include "lltoolgrab.h"
  55. #include "lltoolmgr.h"
  56. #include "llviewermenu.h"
  57. #include "llviewercontrol.h"
  58. #include "llviewerparcelmgr.h"
  59. #include "llviewerwindow.h"
  60. #include "llvoavatarself.h"
  61. #if LL_DARWIN
  62. #include "llresizehandle.h"
  63. // This class draws like an LLResizeHandle but has no interactivity. It's just
  64. // there to provide a cue to the user that the lower right corner of the window
  65. // functions as a resize handle.
  66. class LLFakeResizeHandle final : public LLResizeHandle
  67. {
  68. public:
  69. LLFakeResizeHandle(const std::string& name, const LLRect& rect,
  70. S32 min_width, S32 min_height,
  71. ECorner corner = RIGHT_BOTTOM)
  72. : LLResizeHandle(name, rect, min_width, min_height, corner)
  73. {
  74. }
  75. bool handleHover(S32 x, S32 y, MASK mask) override { return false; };
  76. bool handleMouseDown(S32 x, S32 y, MASK mask) override { return false; };
  77. bool handleMouseUp(S32 x, S32 y, MASK mask) override { return false; };
  78. };
  79. #endif // LL_DARWIN
  80. //
  81. // Globals
  82. //
  83. // Instance created in LLViewerWindow::initWorldUI()
  84. LLToolBar* gToolBarp = NULL;
  85. //
  86. // Statics
  87. //
  88. F32 LLToolBar::sInventoryAutoOpenTime = 1.f;
  89. //
  90. // Functions
  91. //
  92. LLToolBar::LLToolBar(const LLRect& rect)
  93. : LLPanel("tool bar", rect, BORDER_NO)
  94. #if LL_DARWIN
  95. , mResizeHandle(NULL)
  96. #endif // LL_DARWIN
  97. {
  98. llassert_always(gToolBarp == NULL); // Only one instance allowed
  99. setIsChrome(true);
  100. setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM);
  101. LLUICtrlFactory::getInstance()->buildPanel(this, "panel_toolbar.xml");
  102. setFocusRoot(true);
  103. gToolBarp = this;
  104. }
  105. bool LLToolBar::postBuild()
  106. {
  107. mChatButton = getChild<LLButton>("chat_btn");
  108. mChatButton->setClickedCallback(onClickChat, this);
  109. mChatButton->setControlName("ChatVisible", NULL);
  110. mIMButton = getChild<LLButton>("communicate_btn");
  111. mIMButton->setClickedCallback(onClickIM, this);
  112. mIMButton->setControlName("ShowCommunicate", NULL);
  113. mFriendsButton = getChild<LLButton>("friends_btn");
  114. mFriendsButton->setClickedCallback(onClickFriends, this);
  115. mFriendsButton->setControlName("ShowFriends", NULL);
  116. mGroupsButton = getChild<LLButton>("groups_btn");
  117. mGroupsButton->setClickedCallback(onClickGroups, this);
  118. mGroupsButton->setControlName("ShowGroups", NULL);
  119. mFlyButton = getChild<LLButton>("fly_btn");
  120. mFlyButton->setClickedCallback(onClickFly, this);
  121. mFlyButton->setControlName("FlyBtnState", NULL);
  122. mSnapshotButton = getChild<LLButton>("snapshot_btn");
  123. mSnapshotButton->setClickedCallback(onClickSnapshot, this);
  124. mSnapshotButton->setControlName("", NULL);
  125. mSearchButton = getChild<LLButton>("directory_btn");
  126. mSearchButton->setClickedCallback(onClickSearch, this);
  127. mSearchButton->setControlName("ShowSearch", NULL);
  128. mBuildButton = getChild<LLButton>("build_btn");
  129. mBuildButton->setClickedCallback(onClickBuild, this);
  130. mBuildButton->setControlName("BuildBtnState", NULL);
  131. mRadarButton = getChild<LLButton>("radar_btn");
  132. mRadarButton->setClickedCallback(onClickRadar, this);
  133. mRadarButton->setControlName("ShowRadar", NULL);
  134. mMiniMapButton = getChild<LLButton>("minimap_btn");
  135. mMiniMapButton->setClickedCallback(onClickMiniMap, this);
  136. mMiniMapButton->setControlName("ShowMiniMap", NULL);
  137. mMapButton = getChild<LLButton>("map_btn");
  138. mMapButton->setClickedCallback(onClickMap, this);
  139. mMapButton->setControlName("ShowWorldMap", NULL);
  140. mInventoryButton = getChild<LLButton>("inventory_btn");
  141. mInventoryButton->setClickedCallback(onClickInventory, this);
  142. mInventoryButton->setControlName("ShowInventory", NULL);
  143. for (child_list_const_iter_t child_iter = getChildList()->begin();
  144. child_iter != getChildList()->end(); ++child_iter)
  145. {
  146. LLView* view = *child_iter;
  147. LLButton* buttonp = dynamic_cast<LLButton*>(view);
  148. if (buttonp)
  149. {
  150. buttonp->setSoundFlags(LLView::SILENT);
  151. }
  152. }
  153. #if LL_DARWIN
  154. if (mResizeHandle == NULL)
  155. {
  156. LLRect rect(0, 0, RESIZE_HANDLE_WIDTH, RESIZE_HANDLE_HEIGHT);
  157. mResizeHandle = new LLFakeResizeHandle(std::string(""), rect,
  158. RESIZE_HANDLE_WIDTH,
  159. RESIZE_HANDLE_HEIGHT);
  160. this->addChildAtEnd(mResizeHandle);
  161. }
  162. #endif // LL_DARWIN
  163. layoutButtons();
  164. return true;
  165. }
  166. LLToolBar::~LLToolBar()
  167. {
  168. // LLView destructor cleans up children
  169. gToolBarp = NULL;
  170. }
  171. bool LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop,
  172. EDragAndDropType cargo_type,
  173. void* cargo_data,
  174. EAcceptance* accept,
  175. std::string& tooltip_msg)
  176. {
  177. LLFloaterInventory* floaterp = LLFloaterInventory::getActiveFloater();
  178. if (floaterp && floaterp->getVisible())
  179. {
  180. mInventoryAutoOpen = false;
  181. }
  182. else if (mInventoryButton->getRect().pointInRect(x, y))
  183. {
  184. if (mInventoryAutoOpen)
  185. {
  186. if (!(floaterp && floaterp->getVisible()) &&
  187. mInventoryAutoOpenTimer.getElapsedTimeF32() > sInventoryAutoOpenTime)
  188. {
  189. LLFloaterInventory::showAgentInventory();
  190. }
  191. }
  192. else
  193. {
  194. mInventoryAutoOpen = true;
  195. mInventoryAutoOpenTimer.reset();
  196. }
  197. }
  198. return LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data,
  199. accept, tooltip_msg);
  200. }
  201. // static
  202. void LLToolBar::toggle()
  203. {
  204. if (gToolBarp)
  205. {
  206. bool show = gSavedSettings.getBool("ShowToolBar");
  207. gSavedSettings.setBool("ShowToolBar", !show);
  208. gToolBarp->setVisible(!show);
  209. }
  210. }
  211. // static
  212. bool LLToolBar::isVisible()
  213. {
  214. return gToolBarp && gToolBarp->getVisible();
  215. }
  216. void LLToolBar::layoutButtons()
  217. {
  218. // Always spans whole window. JC
  219. constexpr S32 FUDGE_WIDTH_OF_SCREEN = 4;
  220. constexpr S32 PAD = 2;
  221. S32 width = gViewerWindowp->getWindowWidth() + FUDGE_WIDTH_OF_SCREEN;
  222. S32 count = getChildCount();
  223. if (!count) return;
  224. bool show = gSavedSettings.getBool("ShowChatButton");
  225. mChatButton->setVisible(show);
  226. if (!show) --count;
  227. show = gSavedSettings.getBool("ShowIMButton");
  228. mIMButton->setVisible(show);
  229. if (!show) --count;
  230. show = gSavedSettings.getBool("ShowFriendsButton");
  231. mFriendsButton->setVisible(show);
  232. if (!show) --count;
  233. show = gSavedSettings.getBool("ShowGroupsButton");
  234. mGroupsButton->setVisible(show);
  235. if (!show) --count;
  236. show = gSavedSettings.getBool("ShowFlyButton");
  237. mFlyButton->setVisible(show);
  238. if (!show) --count;
  239. show = gSavedSettings.getBool("ShowSnapshotButton");
  240. mSnapshotButton->setVisible(show);
  241. if (!show) --count;
  242. show = gSavedSettings.getBool("ShowSearchButton");
  243. mSearchButton->setVisible(show);
  244. if (!show) --count;
  245. show = gSavedSettings.getBool("ShowBuildButton");
  246. mBuildButton->setVisible(show);
  247. if (!show) --count;
  248. show = gSavedSettings.getBool("ShowRadarButton");
  249. mRadarButton->setVisible(show);
  250. if (!show) --count;
  251. show = gSavedSettings.getBool("ShowMiniMapButton");
  252. mMiniMapButton->setVisible(show);
  253. if (!show) --count;
  254. show = gSavedSettings.getBool("ShowMapButton");
  255. mMapButton->setVisible(show);
  256. if (!show) --count;
  257. show = gSavedSettings.getBool("ShowInventoryButton");
  258. mInventoryButton->setVisible(show);
  259. if (!show) --count;
  260. if (count < 1)
  261. {
  262. // No button in the toolbar ! Hide it.
  263. gSavedSettings.setBool("ShowToolBar", false);
  264. return;
  265. }
  266. #if LL_DARWIN
  267. // this function may be called before postBuild(), in which case
  268. // mResizeHandle won't have been set up yet.
  269. if (mResizeHandle)
  270. {
  271. // a resize handle has been added as a child, increasing the count by
  272. // one.
  273. --count;
  274. if (!gWindowp->getFullscreen())
  275. {
  276. // Only when running in windowed mode on the Mac, leave room for a
  277. // resize widget on the right edge of the bar.
  278. width -= RESIZE_HANDLE_WIDTH;
  279. LLRect r;
  280. r.mLeft = width - PAD;
  281. r.mBottom = 0;
  282. r.mRight = r.mLeft + RESIZE_HANDLE_WIDTH;
  283. r.mTop = r.mBottom + RESIZE_HANDLE_HEIGHT;
  284. mResizeHandle->setRect(r);
  285. mResizeHandle->setVisible(true);
  286. }
  287. else
  288. {
  289. mResizeHandle->setVisible(false);
  290. }
  291. }
  292. #endif // LL_DARWIN
  293. // We actually want to extend "PAD" pixels off the right edge of the
  294. // screen, such that the rightmost button is aligned.
  295. F32 segment_width = (F32)(width + PAD) / (F32)count;
  296. S32 btn_width = lltrunc(segment_width - PAD);
  297. // Evenly space all views
  298. S32 height = -1;
  299. S32 i = count - 1;
  300. for (child_list_const_iter_t child_iter = getChildList()->begin();
  301. child_iter != getChildList()->end(); ++child_iter)
  302. {
  303. LLView* btn_view = *child_iter;
  304. LLButton* buttonp = dynamic_cast<LLButton*>(btn_view);
  305. if (buttonp && btn_view->getVisible())
  306. {
  307. if (height < 0)
  308. {
  309. height = btn_view->getRect().getHeight();
  310. }
  311. S32 x = ll_roundp(i * segment_width);
  312. S32 y = 0;
  313. LLRect r;
  314. r.setOriginAndSize(x, y, btn_width, height);
  315. btn_view->setRect(r);
  316. --i;
  317. }
  318. }
  319. }
  320. // virtual
  321. void LLToolBar::reshape(S32 width, S32 height, bool called_from_parent)
  322. {
  323. LLPanel::reshape(width, height, called_from_parent);
  324. layoutButtons();
  325. }
  326. // Per-frame updates of visibility
  327. void LLToolBar::refresh()
  328. {
  329. // Ensure we use setVisible() on startup:
  330. static S32 previous_visibility = -1;
  331. static LLCachedControl<bool> show_toolbar(gSavedSettings, "ShowToolBar");
  332. bool visible = show_toolbar && !gAgent.cameraMouselook();
  333. if (previous_visibility != (S32)visible)
  334. {
  335. setVisible(visible);
  336. if (visible)
  337. {
  338. // In case there would be no button to show, it would re-hide the
  339. // toolbar (on next frame)
  340. layoutButtons();
  341. }
  342. previous_visibility = (S32)visible;
  343. }
  344. if (!visible) return;
  345. bool sitting = false;
  346. if (isAgentAvatarValid())
  347. {
  348. sitting = gAgentAvatarp->mIsSitting;
  349. }
  350. mFlyButton->setEnabled(!sitting &&
  351. (gAgent.canFly() || gAgent.getFlying()));
  352. //MK
  353. if (gRLenabled)
  354. {
  355. mRadarButton->setEnabled(!gRLInterface.mContainsShownames &&
  356. !gRLInterface.mContainsShownametags);
  357. mMiniMapButton->setEnabled(!gRLInterface.mContainsShowminimap);
  358. mMapButton->setEnabled(!gRLInterface.mContainsShowworldmap &&
  359. !gRLInterface.mContainsShowloc);
  360. mInventoryButton->setEnabled(!gRLInterface.mContainsShowinv);
  361. }
  362. //mk
  363. mBuildButton->setEnabled(gViewerParcelMgr.allowAgentBuild());
  364. }
  365. // static
  366. void LLToolBar::onClickChat(void* user_data)
  367. {
  368. handle_chat(NULL);
  369. }
  370. // static
  371. void LLToolBar::onClickIM(void* user_data)
  372. {
  373. LLFloaterChatterBox::toggleInstance(LLSD());
  374. }
  375. // static
  376. void LLToolBar::onClickFly(void*)
  377. {
  378. gAgent.toggleFlying();
  379. }
  380. // static
  381. void LLToolBar::onClickSnapshot(void*)
  382. {
  383. LLFloaterSnapshot::show(NULL);
  384. }
  385. // static
  386. void LLToolBar::onClickSearch(void*)
  387. {
  388. HBFloaterSearch::toggle();
  389. }
  390. // static
  391. void LLToolBar::onClickBuild(void*)
  392. {
  393. gToolMgr.toggleBuildMode();
  394. }
  395. // static
  396. void LLToolBar::onClickMiniMap(void*)
  397. {
  398. LLFloaterMiniMap::toggleInstance();
  399. }
  400. // static
  401. void LLToolBar::onClickRadar(void*)
  402. {
  403. HBFloaterRadar::toggleInstance();
  404. }
  405. // static
  406. void LLToolBar::onClickMap(void*)
  407. {
  408. LLFloaterWorldMap::toggle(NULL);
  409. }
  410. // static
  411. void LLToolBar::onClickFriends(void*)
  412. {
  413. LLFloaterFriends::toggleInstance();
  414. }
  415. // static
  416. void LLToolBar::onClickGroups(void*)
  417. {
  418. LLFloaterGroups::toggleInstance();
  419. }
  420. // static
  421. void LLToolBar::onClickInventory(void*)
  422. {
  423. handle_inventory(NULL);
  424. }