llmenugl.h 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873
  1. /**
  2. * @file llmenugl.h
  3. * @brief Declaration of the opengl based menu system.
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-2009, 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. #ifndef LL_LLMENUGL_H
  33. #define LL_LLMENUGL_H
  34. #include <list>
  35. #include "llevent.h"
  36. #include "llfloater.h"
  37. #include "llframetimer.h"
  38. #include "llkeyboard.h"
  39. #include "lluistring.h"
  40. #include "llview.h"
  41. #include "llcolor4.h"
  42. // These callbacks are used by the LLMenuItemCallGL and LLMenuItemCheckGL
  43. // classes during their work.
  44. typedef void (*menu_callback)(void*);
  45. // These callbacks are used by the LLMenuItemCallGL classes during their work.
  46. typedef void (*on_disabled_callback)(void*);
  47. // This callback is used by the LLMenuItemCallGL and LLMenuItemCheckGL to
  48. // determine if the current menu is enabled.
  49. typedef bool (*enabled_callback)(void*);
  50. // This callback is used by LLMenuItemCheckGL to determine it is 'checked'
  51. // state.
  52. typedef bool (*check_callback)(void*);
  53. // This callback is potentially used by LLMenuItemCallGL. If provided, this
  54. // function is called whenever it's time to determine the label's contents.
  55. // Put the contents of the label in the provided parameter.
  56. typedef void (*label_callback)(std::string&, void*);
  57. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  58. // Class LLMenuItemGL
  59. //
  60. // The LLMenuItemGL represents a single menu item in a menu.
  61. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  62. class LLMenuItemGL : public LLView
  63. {
  64. public:
  65. // static functions to control the global color scheme.
  66. LL_INLINE static void setEnabledColor(const LLColor4& color) { sEnabledColor = color; }
  67. LL_INLINE static const LLColor4& getEnabledColor() { return sEnabledColor; }
  68. LL_INLINE static void setDisabledColor(const LLColor4& color) { sDisabledColor = color; }
  69. LL_INLINE static const LLColor4& getDisabledColor() { return sDisabledColor; }
  70. LL_INLINE static void setHighlightBGColor(const LLColor4& c) { sHighlightBackground = c; }
  71. LL_INLINE static const LLColor4& getHighlightBGColor() { return sHighlightBackground; }
  72. LL_INLINE static void setHighlightFGColor(const LLColor4& c) { sHighlightForeground = c; }
  73. LL_INLINE static const LLColor4& getHighlightFGColor() { return sHighlightForeground; }
  74. LLMenuItemGL(const std::string& name, const std::string& label,
  75. KEY key = KEY_NONE, MASK = MASK_NONE);
  76. const std::string& getTag() const override;
  77. LLXMLNodePtr getXML(bool save_children = true) const override;
  78. LL_INLINE void setValue(const LLSD& v) override { setLabel(v.asString()); }
  79. LL_INLINE virtual std::string getType() const { return "item"; }
  80. // Sets the font used by this item.
  81. LL_INLINE void setFont(const LLFontGL* font) { mFont = font; }
  82. LL_INLINE const LLFontGL* getFont() const { return mFont; }
  83. LL_INLINE void setFontStyle(U8 style) { mStyle = style; }
  84. LL_INLINE U8 getFontStyle() const { return mStyle; }
  85. // Returns the height in pixels for the current font.
  86. virtual U32 getNominalHeight() const;
  87. // Marks item as not needing space for check marks or accelerator keys
  88. LL_INLINE virtual void setBriefItem(bool b) { mBriefItem = b; }
  89. LL_INLINE virtual bool isBriefItem() const { return mBriefItem; }
  90. void setJumpKey(KEY key);
  91. LL_INLINE KEY getJumpKey() const { return mJumpKey; }
  92. virtual bool addToAcceleratorList(std::list<LLKeyBinding*>* listp);
  93. virtual bool handleAcceleratorKey(KEY key, MASK mask);
  94. LL_INLINE void setAllowKeyRepeat(bool allow) { mAllowKeyRepeat = allow; }
  95. LL_INLINE bool getAllowKeyRepeat() const { return mAllowKeyRepeat; }
  96. // Change the label
  97. LL_INLINE void setLabel(const std::string& l) { mLabel = l; }
  98. LL_INLINE const std::string& getLabel() const { return mLabel.getString(); }
  99. bool setLabelArg(const std::string& key, const std::string& text) override;
  100. // Get the parent menu for this item
  101. virtual class LLMenuGL* getMenu();
  102. // Returns the normal width of this control in pixels - this is used for
  103. // calculating the widest item, as well as for horizontal arrangement.
  104. virtual U32 getNominalWidth() const;
  105. // buildDrawLabel() constructs the string used during the draw() function.
  106. // This reduces the overall string manipulation, but can lead to visual
  107. // errors if the state of the object changes without the knowledge of the
  108. // menu item. For example, if a boolean being watched is changed outside of
  109. // the menu item's doIt() function, the draw buffer will not be updated and
  110. // will reflect the wrong value. If this ever becomes an issue, there are
  111. // ways to fix this. Returns the enabled state of the item.
  112. virtual void buildDrawLabel();
  113. // For branching menu items, bring sub menus up to root level of menu
  114. // hierarchy
  115. LL_INLINE virtual void updateBranchParent(LLView* parentp)
  116. {
  117. }
  118. // Does the primary functionality of the menu item.
  119. virtual void doIt();
  120. virtual void setHighlight(bool highlight);
  121. LL_INLINE virtual bool getHighlight() const { return mHighlight; }
  122. // Determines if this represents an active sub-menu
  123. LL_INLINE virtual bool isActive() const { return false; }
  124. // Determines if this represents an open sub-menu
  125. LL_INLINE virtual bool isOpen() const { return false; }
  126. LL_INLINE virtual void setEnabledSubMenus(bool) {}
  127. // LLView Functionality
  128. bool handleHover(S32 x, S32 y, MASK mask) override;
  129. bool handleKeyHere(KEY key, MASK mask) override;
  130. bool handleMouseDown(S32 x, S32 y, MASK mask) override;
  131. bool handleMouseUp(S32 x, S32 y, MASK mask) override;
  132. void draw() override;
  133. LL_INLINE bool getHover() const { return mGotHover; }
  134. LL_INLINE void setDrawTextDisabled(bool b) { mDrawTextDisabled = b; }
  135. LL_INLINE bool getDrawTextDisabled() const { return mDrawTextDisabled; }
  136. protected:
  137. LL_INLINE void setHover(bool b) { mGotHover = b; }
  138. // This function appends the character string representation of
  139. // the current accelerator key and mask to the provided string.
  140. void appendAcceleratorString(std::string& st) const;
  141. protected:
  142. KEY mAcceleratorKey;
  143. MASK mAcceleratorMask;
  144. // mLabel contains the actual label specified by the user.
  145. LLUIString mLabel;
  146. // The draw labels contain some of the labels that we draw during the
  147. // draw() routine. This optimizes away some of the string manipulation.
  148. LLUIString mDrawBoolLabel;
  149. LLUIString mDrawAccelLabel;
  150. LLUIString mDrawBranchLabel;
  151. bool mHighlight;
  152. private:
  153. static LLColor4 sEnabledColor;
  154. static LLColor4 sDisabledColor;
  155. static LLColor4 sHighlightBackground;
  156. static LLColor4 sHighlightForeground;
  157. // Keyboard and mouse variables
  158. bool mAllowKeyRepeat;
  159. bool mGotHover;
  160. // If true, suppress normal space for check marks on the left and
  161. // accelerator keys on the right.
  162. bool mBriefItem;
  163. // Font for this item
  164. const LLFontGL* mFont;
  165. U8 mStyle;
  166. bool mDrawTextDisabled;
  167. KEY mJumpKey;
  168. };
  169. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  170. // Class LLMenuItemCallGL
  171. //
  172. // The LLMenuItemCallerGL represents a single menu item in a menu that calls a
  173. // user defined callback.
  174. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  175. class LLMenuItemCallGL : public LLMenuItemGL, public LLOldEvents::LLObservable
  176. {
  177. public:
  178. // Normal constructors
  179. LLMenuItemCallGL(const std::string& name,
  180. menu_callback clicked_cb,
  181. enabled_callback enabled_cb = NULL,
  182. void* user_data = NULL,
  183. KEY key = KEY_NONE, MASK mask = MASK_NONE,
  184. bool enabled = true,
  185. on_disabled_callback on_disabled_cb = NULL);
  186. LLMenuItemCallGL(const std::string& name,
  187. const std::string& label,
  188. menu_callback clicked_cb,
  189. enabled_callback enabled_cb = NULL,
  190. void* user_data = NULL,
  191. KEY key = KEY_NONE, MASK mask = MASK_NONE,
  192. bool enabled = true,
  193. on_disabled_callback on_disabled_cb = NULL);
  194. // Constructors for when you want to trap the arrange method.
  195. LLMenuItemCallGL(const std::string& name,
  196. const std::string& label,
  197. menu_callback clicked_cb,
  198. enabled_callback enabled_cb,
  199. label_callback label_cb,
  200. void* user_data,
  201. KEY key = KEY_NONE, MASK mask = MASK_NONE,
  202. bool enabled = true,
  203. on_disabled_callback on_disabled_c = NULL);
  204. LLMenuItemCallGL(const std::string& name,
  205. menu_callback clicked_cb,
  206. enabled_callback enabled_cb,
  207. label_callback label_cb,
  208. void* user_data,
  209. KEY key = KEY_NONE, MASK mask = MASK_NONE,
  210. bool enabled = true,
  211. on_disabled_callback on_disabled_c = NULL);
  212. const std::string& getTag() const override;
  213. LLXMLNodePtr getXML(bool save_children = true) const override;
  214. LL_INLINE std::string getType() const override { return "call"; }
  215. void setEnabledControl(const std::string& enabled_ctrl, LLView* context);
  216. void setVisibleControl(const std::string& enabled_ctrl, LLView* context);
  217. LL_INLINE void setMenuCallback(menu_callback callback, void* data)
  218. {
  219. mCallback = callback;
  220. mUserData = data;
  221. }
  222. LL_INLINE menu_callback getMenuCallback() const { return mCallback; }
  223. LL_INLINE void setEnabledCallback(enabled_callback cb)
  224. {
  225. mEnabledCallback = cb;
  226. }
  227. LL_INLINE void setUserData(void* userdata) { mUserData = userdata; }
  228. LL_INLINE void* getUserData() const { return mUserData; }
  229. // Called to rebuild the draw label
  230. void buildDrawLabel() override;
  231. // Does the primary funcationality of the menu item.
  232. void doIt() override;
  233. bool handleAcceleratorKey(KEY key, MASK mask) override;
  234. private:
  235. menu_callback mCallback;
  236. // mEnabledCallback should return true if the item should be enabled
  237. enabled_callback mEnabledCallback;
  238. label_callback mLabelCallback;
  239. void* mUserData;
  240. on_disabled_callback mOnDisabledCallback;
  241. };
  242. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  243. // Class LLMenuItemCheckGL
  244. //
  245. // The LLMenuItemCheckGL is an extension of the LLMenuItemCallGL class, by
  246. // allowing another method to be specified which determines if the menu item
  247. // should consider itself checked as true or not. Be careful that the provided
  248. // callback is fast - it needs to be VERY FUCKING EFFICIENT, because it may
  249. // need to be checked a lot.
  250. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  251. class LLMenuItemCheckGL : public LLMenuItemCallGL
  252. {
  253. public:
  254. LLMenuItemCheckGL(const std::string& name, const std::string& label,
  255. menu_callback callback, enabled_callback enabled_cb,
  256. check_callback check, void* user_data,
  257. KEY key = KEY_NONE, MASK mask = MASK_NONE);
  258. LLMenuItemCheckGL(const std::string& name, menu_callback callback,
  259. enabled_callback enabled_cb, check_callback check,
  260. void* user_data, KEY key = KEY_NONE,
  261. MASK mask = MASK_NONE);
  262. LLMenuItemCheckGL(const std::string& name, const std::string& label,
  263. menu_callback callback, enabled_callback enabled_cb,
  264. const char* control_name, LLView* context, void* data,
  265. KEY key = KEY_NONE, MASK mask = MASK_NONE);
  266. const std::string& getTag() const override;
  267. LLXMLNodePtr getXML(bool save_children = true) const override;
  268. void setCheckedControl(std::string checked_control, LLView* context);
  269. LL_INLINE void setCheckCallback(check_callback cb) { mCheckCallback = cb; }
  270. void setValue(const LLSD& value) override;
  271. LL_INLINE std::string getType() const override { return "check"; }
  272. // Called to rebuild the draw label
  273. void buildDrawLabel() override;
  274. private:
  275. check_callback mCheckCallback;
  276. bool mChecked;
  277. };
  278. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  279. // Class LLMenuItemToggleGL
  280. //
  281. // The LLMenuItemToggleGL is a menu item that wraps around a user
  282. // specified and controlled boolean.
  283. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  284. class LLMenuItemToggleGL : public LLMenuItemGL
  285. {
  286. public:
  287. LLMenuItemToggleGL(const std::string& name, const std::string& label,
  288. bool* toggle, KEY key = KEY_NONE,
  289. MASK mask = MASK_NONE);
  290. LLMenuItemToggleGL(const std::string& name, bool* toggle,
  291. KEY key = KEY_NONE, MASK mask = MASK_NONE);
  292. // There is no getXML() because we cannot reference the toggled global
  293. // variable by XML use LLMenuItemCheckGL instead.
  294. LL_INLINE std::string getType() const override { return "toggle"; }
  295. // called to rebuild the draw label
  296. void buildDrawLabel() override;
  297. // Does the primary funcationality of the menu item.
  298. void doIt() override;
  299. private:
  300. bool* mToggle;
  301. };
  302. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  303. // Class LLMenuGL
  304. //
  305. // The Menu class represents a normal rectangular menu somewhere on screen. A
  306. // Menu can have menu items (described above) or sub-menus attached to it.
  307. // Sub-menus are implemented via a specialized menu-item type known as a
  308. // branch. Since it's easy to do wrong, I've taken the branch functionality out
  309. // of public view, and encapsulate it in the appendMenu() method.
  310. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  311. // *TODO: the menu and menu item classes share a great deal of functionality
  312. // and perhaps should be united. I think it may make the most sense to make
  313. // LLMenuGL be a subclass of LLMenuItemGL. -MG
  314. class LLMenuGL : public LLUICtrl
  315. {
  316. friend class LLMenuItemBranchGL;
  317. protected:
  318. LOG_CLASS(LLMenuGL);
  319. public:
  320. LLMenuGL(const std::string& name, const std::string& label,
  321. LLHandle<LLFloater> parent_floater = LLHandle<LLFloater>());
  322. LLMenuGL(const std::string& label,
  323. LLHandle<LLFloater> parent_floater = LLHandle<LLFloater>());
  324. ~LLMenuGL() override;
  325. const std::string& getTag() const override;
  326. LLXMLNodePtr getXML(bool save_children = true) const override;
  327. static LLView* fromXML(LLXMLNodePtr node, LLView* parent,
  328. LLUICtrlFactory* factory);
  329. void parseChildXML(LLXMLNodePtr child, LLView* parent,
  330. LLUICtrlFactory* factory);
  331. // LLView Functionality
  332. bool handleUnicodeCharHere(llwchar uni_char) override;
  333. bool handleHover(S32 x, S32 y, MASK mask) override;
  334. void setVisible(bool visible) override;
  335. void draw() override;
  336. void deleteAllChildren() override;
  337. virtual void drawBackground(LLMenuItemGL* itemp, LLColor4& color);
  338. virtual bool handleAcceleratorKey(KEY key, MASK mask);
  339. LLMenuGL* getChildMenuByName(const char* name, bool recurse) const;
  340. bool clearHoverItem();
  341. LL_INLINE const std::string& getLabel() const { return mLabel.getString(); }
  342. LL_INLINE void setLabel(const std::string& label) { mLabel = label; }
  343. // background colors
  344. static void setDefaultBackgroundColor(const LLColor4& color)
  345. {
  346. sDefaultBackgroundColor = color;
  347. }
  348. LL_INLINE void setBackgroundColor(const LLColor4& c)
  349. {
  350. mBackgroundColor = c;
  351. }
  352. LL_INLINE const LLColor4& getBackgroundColor() const
  353. {
  354. return mBackgroundColor;
  355. }
  356. LL_INLINE void setBackgroundVisible(bool b) { mBgVisible = b; }
  357. void setCanTearOff(bool tear_off,
  358. LLHandle<LLFloater> parent_handle = LLHandle<LLFloater>());
  359. // Adds the menu item to this menu.
  360. virtual bool append(LLMenuItemGL* item);
  361. // Removes a menu item from this menu.
  362. virtual bool remove(LLMenuItemGL* item);
  363. // *NOTE: Mani - appendNoArrange() should be removed when merging to
  364. // skinning/viewer 2.0. It's added as a fix to a viewer 1.23 bug that has
  365. // already been address by skinning work.
  366. virtual bool appendNoArrange(LLMenuItemGL* item);
  367. // Adds a separator to this menu
  368. virtual bool appendSeparator(const std::string& name = LLStringUtil::null);
  369. // Adds a menu: this will create a cascading menu
  370. virtual bool appendMenu(LLMenuGL* menu);
  371. // For branching menu items, bring sub menus up to root level of menu
  372. // hierarchy
  373. virtual void updateParent(LLView* parentp);
  374. // Passes the name and the enable flag for a menu item.
  375. // true will make sure it is enabled, false will disable it.
  376. void setItemEnabled(const std::string& name, bool enable);
  377. // propagate message to submenus
  378. void setEnabledSubMenus(bool enable);
  379. void setItemVisible(const std::string& name, bool visible);
  380. void setItemLabel(const std::string& name, const std::string& label);
  381. // sets the left,bottom corner of menu, useful for popups
  382. void setLeftAndBottom(S32 left, S32 bottom);
  383. virtual bool handleJumpKey(KEY key);
  384. virtual bool jumpKeysActive();
  385. virtual bool isOpen();
  386. // Shapes this menu to fit the current state of the children, and adjusts
  387. // the child rects to fit. This is called automatically when you add items.
  388. // *FIXME: we may need to deal with visibility arrangement.
  389. virtual void arrange();
  390. // Removes all items on the menu
  391. void empty();
  392. void setItemLastSelected(LLMenuItemGL* item); // Must be in menu
  393. U32 getItemCount(); // Number of menu items
  394. LLMenuItemGL* getItem(S32 number); // 0 = first item
  395. LLMenuItemGL* getItem(const std::string& name);
  396. LLMenuItemGL* getHighlightedItem();
  397. LLMenuItemGL* highlightNextItem(LLMenuItemGL* cur_item,
  398. bool skip_disabled = true);
  399. LLMenuItemGL* highlightPrevItem(LLMenuItemGL* cur_item,
  400. bool skip_disabled = true);
  401. void buildDrawLabels();
  402. void createJumpKeys();
  403. // Show popup in global screen space based on last mouse location.
  404. static void showPopup(LLMenuGL* menu);
  405. // Show popup at a specific location.
  406. static void showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y);
  407. // Whether to drop shadow menu bar
  408. LL_INLINE void setDropShadowed(bool b) { mDropShadowed = b; }
  409. LL_INLINE void setParentMenuItem(LLMenuItemGL* p) { mParentMenuItem = p; }
  410. LL_INLINE LLMenuItemGL* getParentMenuItem() const { return mParentMenuItem; }
  411. LL_INLINE void setTornOff(bool b) { mTornOff = b; }
  412. LL_INLINE bool getTornOff() { return mTornOff; }
  413. LL_INLINE bool getCanTearOff() { return mTearOffItem != NULL; }
  414. LL_INLINE KEY getJumpKey() const { return mJumpKey; }
  415. LL_INLINE void setJumpKey(KEY key) { mJumpKey = key; }
  416. LL_INLINE static void setKeyboardMode(bool mode) { sKeyboardMode = mode; }
  417. LL_INLINE static bool getKeyboardMode() { return sKeyboardMode; }
  418. protected:
  419. void createSpilloverBranch();
  420. void cleanupSpilloverBranch();
  421. public:
  422. static class LLMenuHolderGL* sMenuContainer;
  423. protected:
  424. // *TODO: create accessor methods for these ?
  425. typedef std::list<LLMenuItemGL*> item_list_t;
  426. item_list_t mItems;
  427. typedef std::map<KEY, LLMenuItemGL*> navigation_key_map_t;
  428. navigation_key_map_t mJumpKeys;
  429. S32 mLastMouseX;
  430. S32 mLastMouseY;
  431. S32 mMouseVelX;
  432. S32 mMouseVelY;
  433. bool mHorizontalLayout;
  434. bool mKeepFixedSize;
  435. private:
  436. static LLColor4 sDefaultBackgroundColor;
  437. static bool sKeyboardMode;
  438. LLColor4 mBackgroundColor;
  439. bool mBgVisible;
  440. LLMenuItemGL* mParentMenuItem;
  441. LLUIString mLabel;
  442. bool mDropShadowed; // Whether to drop shadow
  443. bool mHasSelection;
  444. LLFrameTimer mFadeTimer;
  445. bool mTornOff;
  446. class LLMenuItemTearOffGL* mTearOffItem;
  447. class LLMenuItemBranchGL* mSpilloverBranch;
  448. LLMenuGL* mSpilloverMenu;
  449. LLHandle<LLFloater> mParentFloaterHandle;
  450. KEY mJumpKey;
  451. };
  452. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  453. // Class LLMenuItemBranchGL
  454. //
  455. // The LLMenuItemBranchGL represents a menu item that has a sub-menu. This is
  456. // used to make cascading menus.
  457. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  458. class LLMenuItemBranchGL : public LLMenuItemGL
  459. {
  460. public:
  461. LLMenuItemBranchGL(const std::string& name, const std::string& label,
  462. LLHandle<LLView> branch,
  463. KEY key = KEY_NONE, MASK mask = MASK_NONE);
  464. ~LLMenuItemBranchGL() override;
  465. const std::string& getTag() const override;
  466. LLXMLNodePtr getXML(bool save_children = true) const override;
  467. LL_INLINE std::string getType() const override { return "menu"; }
  468. bool handleMouseUp(S32 x, S32 y, MASK mask) override;
  469. bool handleAcceleratorKey(KEY key, MASK mask) override;
  470. // Check if we've used these accelerators already
  471. bool addToAcceleratorList(std::list <LLKeyBinding*>* listp) override;
  472. // Called to rebuild the draw label
  473. void buildDrawLabel() override;
  474. // Does the primary funcationality of the menu item.
  475. void doIt() override;
  476. bool handleKey(KEY key, MASK mask, bool called_from_parent) override;
  477. bool handleUnicodeChar(llwchar uni_char, bool called_from_parent) override;
  478. // Sets the hover status (called by it's menu) and if the object is
  479. // active. This is used for behavior transfer.
  480. void setHighlight(bool highlight) override;
  481. bool handleKeyHere(KEY key, MASK mask) override;
  482. LL_INLINE bool isActive() const override { return isOpen() && getBranch()->getHighlightedItem(); }
  483. LL_INLINE bool isOpen() const override { return getBranch() && getBranch()->isOpen(); }
  484. LL_INLINE LLMenuGL* getBranch() const { return (LLMenuGL*)(mBranch.get()); }
  485. void updateBranchParent(LLView* parentp) override;
  486. LL_INLINE void setEnabledSubMenus(bool enabled) override
  487. {
  488. if (getBranch())
  489. {
  490. getBranch()->setEnabledSubMenus(enabled);
  491. }
  492. }
  493. virtual void openMenu();
  494. // LLView Functionality
  495. void onVisibilityChange(bool visible) override;
  496. void draw() override;
  497. LLView* getChildView(const char* name, bool recurse = true,
  498. bool create_if_missing = true) const override;
  499. private:
  500. LLHandle<LLView> mBranch;
  501. };
  502. //-----------------------------------------------------------------------------
  503. // class LLPieMenu
  504. // A circular menu of items, icons, etc.
  505. //-----------------------------------------------------------------------------
  506. class LLPieMenu : public LLMenuGL
  507. {
  508. public:
  509. LLPieMenu(const std::string& name, const std::string& label);
  510. LLPieMenu(const std::string& name);
  511. const std::string& getTag() const override;
  512. LLXMLNodePtr getXML(bool save_children = true) const override;
  513. void initXML(LLXMLNodePtr node, LLView* context, LLUICtrlFactory* factory);
  514. // LLView Functionality
  515. // Cannot set visibility directly: must call show or hide
  516. void setVisible(bool visible) override;
  517. bool handleHover(S32 x, S32 y, MASK mask) override;
  518. bool handleMouseDown(S32 x, S32 y, MASK mask) override;
  519. bool handleRightMouseDown(S32 x, S32 y, MASK mask) override;
  520. bool handleRightMouseUp(S32 x, S32 y, MASK mask) override;
  521. bool handleMouseUp(S32 x, S32 y, MASK mask) override;
  522. void draw() override;
  523. void drawBackground(LLMenuItemGL* itemp, LLColor4& color) override;
  524. bool append(LLMenuItemGL* item) override;
  525. bool appendSeparator(const std::string& name = LLStringUtil::null) override;
  526. bool appendPieMenu(LLPieMenu* menu);
  527. void arrange() override;
  528. // Display the menu centered on this point on the screen.
  529. void show(S32 x, S32 y, bool mouse_down);
  530. void hide(bool item_selected);
  531. private:
  532. LLMenuItemGL* pieItemFromXY(S32 x, S32 y);
  533. S32 pieItemIndexFromXY(S32 x, S32 y);
  534. #if 0 // These cause menu items to be spuriously selected by right-clicks
  535. // near the window edge at low frame rates. I don't think they are
  536. // needed unless you shift the menu position in the draw() function. JC
  537. S32 mShiftHoriz; // non-zero if menu had to shift this frame
  538. S32 mShiftVert; // non-zero if menu had to shift this frame
  539. #endif
  540. bool mFirstMouseDown; // true from show until mouse up
  541. bool mRightMouseDown;
  542. // allow picking pie menu items anywhere outside of center circle:
  543. bool mUseInfiniteRadius;
  544. LLMenuItemGL* mHoverItem;
  545. bool mHoverThisFrame;
  546. bool mHoveredAnyItem;
  547. LLFrameTimer mShrinkBorderTimer;
  548. // For rendering pie menus as both bounded and unbounded:
  549. F32 mOuterRingAlpha;
  550. F32 mCurRadius;
  551. };
  552. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  553. // Class LLMenuBarGL
  554. //
  555. // A menu bar displays menus horizontally.
  556. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  557. class LLMenuBarGL : public LLMenuGL
  558. {
  559. public:
  560. LLMenuBarGL(const std::string& name);
  561. ~LLMenuBarGL() override;
  562. const std::string& getTag() const override;
  563. LLXMLNodePtr getXML(bool save_children = true) const override;
  564. static LLView* fromXML(LLXMLNodePtr node, LLView* parent,
  565. LLUICtrlFactory* factory);
  566. // LLView Functionality
  567. bool handleHover(S32 x, S32 y, MASK mask) override;
  568. bool handleKeyHere(KEY key, MASK mask) override;
  569. bool handleMouseDown(S32 x, S32 y, MASK mask) override;
  570. bool handleRightMouseDown(S32 x, S32 y, MASK mask) override;
  571. void draw() override;
  572. bool jumpKeysActive() override;
  573. bool handleJumpKey(KEY key) override;
  574. bool handleAcceleratorKey(KEY key, MASK mask) override;
  575. // Rearranges the child rects so they fit the shape of the menu bar.
  576. void arrange() override;
  577. // Add a vertical separator to this menu
  578. bool appendSeparator(const std::string& name = LLStringUtil::null) override;
  579. // Adds a menu; this will create a drop down menu.
  580. bool appendMenu(LLMenuGL* menu) override;
  581. // Returns x position of rightmost child, usually Help menu
  582. S32 getRightmostMenuEdge();
  583. LL_INLINE void resetMenuTrigger() { mAltKeyTrigger = false; }
  584. private:
  585. void checkMenuTrigger();
  586. private:
  587. std::list <LLKeyBinding*> mAccelerators;
  588. bool mAltKeyTrigger;
  589. };
  590. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  591. // Class LLMenuHolderGL
  592. //
  593. // High level view that serves as parent for all menus
  594. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  595. class LLMenuHolderGL : public LLPanel
  596. {
  597. public:
  598. LLMenuHolderGL();
  599. LLMenuHolderGL(const std::string& name, const LLRect& rect,
  600. bool mouse_opaque, U32 follows = FOLLOWS_NONE);
  601. void reshape(S32 width, S32 height, bool call_from_parent = true) override;
  602. virtual bool hideMenus();
  603. LL_INLINE void setCanHide(bool can_hide) { mCanHide = can_hide; }
  604. // LLView functionality
  605. void draw() override;
  606. bool handleMouseDown(S32 x, S32 y, MASK mask) override;
  607. bool handleRightMouseDown(S32 x, S32 y, MASK mask) override;
  608. LL_INLINE virtual const LLRect getMenuRect() const { return getLocalRect(); }
  609. virtual bool hasVisibleMenu() const;
  610. static void setActivatedItem(LLMenuItemGL* item);
  611. private:
  612. bool mCanHide;
  613. static LLHandle<LLView> sItemLastSelectedHandle;
  614. static LLFrameTimer sItemActivationTimer;
  615. };
  616. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  617. // Class LLTearOffMenu
  618. //
  619. // Floater that hosts a menu
  620. // https://wiki.lindenlab.com/mediawiki/index.php?title=LLTearOffMenu&oldid=81344
  621. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  622. class LLTearOffMenu : public LLFloater
  623. {
  624. public:
  625. static LLTearOffMenu* create(LLMenuGL* menup);
  626. void onClose(bool app_quitting) override;
  627. void draw() override;
  628. void onFocusReceived() override;
  629. void onFocusLost() override;
  630. bool handleUnicodeChar(llwchar uni_char, bool called_from_parent) override;
  631. bool handleKeyHere(KEY key, MASK mask) override;
  632. void translate(S32 x, S32 y) override;
  633. private:
  634. LLTearOffMenu(LLMenuGL* menup);
  635. private:
  636. LLView* mOldParent;
  637. LLMenuGL* mMenu;
  638. F32 mTargetHeight;
  639. };
  640. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  641. // Class LLMenuItemTearOffGL
  642. //
  643. // This class represents a separator.
  644. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  645. class LLMenuItemTearOffGL : public LLMenuItemGL
  646. {
  647. public:
  648. LLMenuItemTearOffGL(LLHandle<LLFloater> parent_handle = LLHandle<LLFloater>());
  649. const std::string& getTag() const override;
  650. LLXMLNodePtr getXML(bool save_children = true) const override;
  651. void draw() override;
  652. LL_INLINE std::string getType() const override { return "tearoff_menu"; }
  653. void doIt() override;
  654. U32 getNominalHeight() const override;
  655. private:
  656. LLHandle<LLFloater> mParentHandle;
  657. };
  658. extern const std::string LL_PIE_MENU_TAG;
  659. #endif // LL_LLMENUGL_H