PageRenderTime 123ms CodeModel.GetById 54ms app.highlight 62ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/llui/llmenugl.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 874 lines | 511 code | 190 blank | 173 comment | 3 complexity | 849da6aa6e39ac344ffb1beea9d806aa MD5 | raw file
  1/** 
  2 * @file llmenugl.h
  3 * @brief Declaration of the opengl based menu system.
  4 *
  5 * $LicenseInfo:firstyear=2001&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
 27#ifndef LL_LLMENUGL_H
 28#define LL_LLMENUGL_H
 29
 30#include <list>
 31
 32#include "llstring.h"
 33#include "v4color.h"
 34#include "llframetimer.h"
 35
 36#include "llkeyboard.h"
 37#include "llfloater.h"
 38#include "lluistring.h"
 39#include "llview.h"
 40#include <boost/function.hpp>
 41
 42extern S32 MENU_BAR_HEIGHT;
 43extern S32 MENU_BAR_WIDTH;
 44
 45//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 46// Class LLMenuItemGL
 47//
 48// The LLMenuItemGL represents a single menu item in a menu. 
 49//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 50
 51class LLMenuItemGL : public LLUICtrl
 52{
 53public:
 54	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
 55	{
 56		Optional<std::string>	shortcut;
 57		Optional<KEY>			jump_key;
 58		Optional<bool>			use_mac_ctrl,
 59								allow_key_repeat;
 60
 61		Ignored					rect,
 62								left,
 63								top,
 64								right,
 65								bottom,
 66								width,
 67								height,
 68								bottom_delta,
 69								left_delta;
 70
 71		Optional<LLUIColor>		enabled_color,
 72								disabled_color,
 73								highlight_bg_color,
 74								highlight_fg_color;
 75
 76
 77		Params();
 78	};
 79
 80protected:
 81	LLMenuItemGL(const Params&);
 82	friend class LLUICtrlFactory;
 83public:
 84	// LLView overrides
 85	/*virtual*/ void handleVisibilityChange(BOOL new_visibility);
 86	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
 87	/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
 88	/*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
 89
 90	// LLUICtrl overrides
 91	/*virtual*/ void setValue(const LLSD& value);
 92	/*virtual*/ LLSD getValue() const;
 93
 94	virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
 95
 96	LLColor4 getHighlightBgColor() { return mHighlightBackground.get(); }
 97
 98	void setJumpKey(KEY key);
 99	KEY getJumpKey() const { return mJumpKey; }
100	
101	// set the font used by this item.
102	void setFont(const LLFontGL* font) { mFont = font; }
103	const LLFontGL* getFont() const { return mFont; }
104
105	// returns the height in pixels for the current font.
106	virtual U32 getNominalHeight( void ) const;
107	
108	// Marks item as not needing space for check marks or accelerator keys
109	virtual void setBriefItem(BOOL brief);
110	virtual BOOL isBriefItem() const;
111
112	virtual BOOL addToAcceleratorList(std::list<LLKeyBinding*> *listp);
113	void setAllowKeyRepeat(BOOL allow) { mAllowKeyRepeat = allow; }
114	BOOL getAllowKeyRepeat() const { return mAllowKeyRepeat; }
115
116	// change the label
117	void setLabel( const LLStringExplicit& label ) { mLabel = label; }	
118	std::string getLabel( void ) const { return mLabel.getString(); }
119	virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
120
121	// Get the parent menu for this item
122	virtual class LLMenuGL*	getMenu() const;
123
124	// returns the normal width of this control in pixels - this is
125	// used for calculating the widest item, as well as for horizontal
126	// arrangement.
127	virtual U32 getNominalWidth( void ) const;
128
129	// buildDrawLabel() - constructs the string used during the draw()
130	// function. This reduces the overall string manipulation, but can
131	// lead to visual errors if the state of the object changes
132	// without the knowledge of the menu item. For example, if a
133	// boolean being watched is changed outside of the menu item's
134	// onCommit() function, the draw buffer will not be updated and will
135	// reflect the wrong value. If this ever becomes an issue, there
136	// are ways to fix this.
137	// Returns the enabled state of the item.
138	virtual void buildDrawLabel( void );
139
140	// for branching menu items, bring sub menus up to root level of menu hierarchy
141	virtual void updateBranchParent( LLView* parentp ){};
142	
143	virtual void onCommit( void );
144
145	virtual void setHighlight( BOOL highlight );
146	virtual BOOL getHighlight() const { return mHighlight; }
147
148	// determine if this represents an active sub-menu
149	virtual BOOL isActive( void ) const { return FALSE; }
150
151	// determine if this represents an open sub-menu
152	virtual BOOL isOpen( void ) const { return FALSE; }
153
154	virtual void setEnabledSubMenus(BOOL enable){};
155
156	// LLView Functionality
157	virtual BOOL handleKeyHere( KEY key, MASK mask );
158	virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
159	virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask );
160	virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
161	virtual void draw( void );
162
163	BOOL getHover() const { return mGotHover; }
164
165	void setDrawTextDisabled(BOOL disabled) { mDrawTextDisabled = disabled; }
166	BOOL getDrawTextDisabled() const { return mDrawTextDisabled; }
167
168protected:
169	void setHover(BOOL hover) { mGotHover = hover; }
170
171	// This function appends the character string representation of
172	// the current accelerator key and mask to the provided string.
173	void appendAcceleratorString( std::string& st ) const;
174		
175protected:
176	KEY mAcceleratorKey;
177	MASK mAcceleratorMask;
178	// mLabel contains the actual label specified by the user.
179	LLUIString mLabel;
180
181	// The draw labels contain some of the labels that we draw during
182	// the draw() routine. This optimizes away some of the string
183	// manipulation.
184	LLUIString mDrawBoolLabel;
185	LLUIString mDrawAccelLabel;
186	LLUIString mDrawBranchLabel;
187
188	LLUIColor mEnabledColor;
189	LLUIColor mDisabledColor;
190	LLUIColor mHighlightBackground;
191	LLUIColor mHighlightForeground;
192
193	BOOL mHighlight;
194private:
195	// Keyboard and mouse variables
196	BOOL mAllowKeyRepeat;
197	BOOL mGotHover;
198
199	// If true, suppress normal space for check marks on the left and accelerator
200	// keys on the right.
201	BOOL mBriefItem;
202
203	// Font for this item
204	const LLFontGL* mFont;
205	BOOL mDrawTextDisabled;
206
207	KEY mJumpKey;
208};
209
210//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
211// Class LLMenuItemSeparatorGL
212//
213// This class represents a separator.
214//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
215class LLMenuItemSeparatorGL : public LLMenuItemGL
216{
217public:
218	struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>
219	{
220		Params();
221	};
222	LLMenuItemSeparatorGL(const LLMenuItemSeparatorGL::Params& p = LLMenuItemSeparatorGL::Params());
223
224	/*virtual*/ void draw( void );
225	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
226	/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
227	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
228
229	/*virtual*/ U32 getNominalHeight( void ) const;
230};
231
232//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
233// Class LLMenuItemCallGL
234//
235// The LLMenuItemCallerGL represents a single menu item in a menu that
236// calls a user defined callback.
237//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
238
239class LLMenuItemCallGL : public LLMenuItemGL
240{
241public:
242	struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>
243	{
244		Optional<EnableCallbackParam > on_enable;
245		Optional<CommitCallbackParam > on_click;
246		Optional<EnableCallbackParam > on_visible;
247		Params()
248			: on_enable("on_enable"),
249			  on_click("on_click"),
250			  on_visible("on_visible")
251		{}
252	};
253protected:
254	LLMenuItemCallGL(const Params&);
255	friend class LLUICtrlFactory;
256	void updateEnabled( void );
257	void updateVisible( void );
258
259public:
260	void initFromParams(const Params& p);
261	
262	// called to rebuild the draw label
263	virtual void buildDrawLabel( void );
264
265	virtual void onCommit( void );
266
267	virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
268	virtual BOOL handleKeyHere(KEY key, MASK mask);
269	
270	//virtual void draw();
271	
272	boost::signals2::connection setClickCallback( const commit_signal_t::slot_type& cb )
273	{
274		return setCommitCallback(cb);
275	}
276	
277	boost::signals2::connection setEnableCallback( const enable_signal_t::slot_type& cb )
278	{
279		return mEnableSignal.connect(cb);
280	}
281		
282private:
283	enable_signal_t mEnableSignal;
284	enable_signal_t mVisibleSignal;
285};
286
287//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
288// Class LLMenuItemCheckGL
289//
290// The LLMenuItemCheckGL is an extension of the LLMenuItemCallGL
291// class, by allowing another method to be specified which determines
292// if the menu item should consider itself checked as true or not.  Be
293// careful that the provided callback is fast - it needs to be VERY
294// EFFICIENT because it may need to be checked a lot.
295//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
296
297class LLMenuItemCheckGL 
298:	public LLMenuItemCallGL
299{
300public:
301	struct Params : public LLInitParam::Block<Params, LLMenuItemCallGL::Params>
302	{
303		Optional<EnableCallbackParam > on_check;
304		Params()
305		:	on_check("on_check")
306		{}
307	};
308
309protected:
310	LLMenuItemCheckGL(const Params&);
311	friend class LLUICtrlFactory;
312public:
313	
314	void initFromParams(const Params& p);
315
316	virtual void onCommit( void );
317	
318	virtual void setValue(const LLSD& value);
319	virtual LLSD getValue() const;
320
321	// called to rebuild the draw label
322	virtual void buildDrawLabel( void );
323	
324	boost::signals2::connection setCheckCallback( const enable_signal_t::slot_type& cb )
325	{
326		return mCheckSignal.connect(cb);
327	}
328	
329private:
330	enable_signal_t mCheckSignal;
331};
332
333//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
334// Class LLMenuGL
335//
336// The Menu class represents a normal rectangular menu somewhere on
337// screen. A Menu can have menu items (described above) or sub-menus
338// attached to it. Sub-menus are implemented via a specialized
339// menu-item type known as a branch. Since it's easy to do wrong, I've
340// taken the branch functionality out of public view, and encapsulate
341// it in the appendMenu() method.
342//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
343
344// child widget registry
345struct MenuRegistry : public LLChildRegistry<MenuRegistry>
346{};
347
348
349class LLMenuGL 
350:	public LLUICtrl
351{
352public:
353	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
354	{
355		Optional<KEY>					jump_key;
356		Optional<bool>					horizontal_layout,
357										can_tear_off,
358										drop_shadow,
359										bg_visible,
360										create_jump_keys,
361										keep_fixed_size,
362										scrollable;
363		Optional<U32>					max_scrollable_items;
364		Optional<U32>					preferred_width;
365		Optional<LLUIColor>				bg_color;
366		Optional<S32>					shortcut_pad;
367
368		Params()
369		:	jump_key("jump_key", KEY_NONE),
370			horizontal_layout("horizontal_layout"),
371			can_tear_off("tear_off", false),
372			drop_shadow("drop_shadow", true),
373			bg_visible("bg_visible", true),
374			create_jump_keys("create_jump_keys", false),
375			keep_fixed_size("keep_fixed_size", false),
376			bg_color("bg_color",  LLUIColorTable::instance().getColor( "MenuDefaultBgColor" )),
377			scrollable("scrollable", false), 
378			max_scrollable_items("max_scrollable_items", U32_MAX),
379			preferred_width("preferred_width", U32_MAX),
380			shortcut_pad("shortcut_pad")
381		{
382			addSynonym(bg_visible, "opaque");
383			addSynonym(bg_color, "color");
384			addSynonym(can_tear_off, "can_tear_off");
385		}
386	};
387
388	// my valid children are contained in MenuRegistry
389	typedef MenuRegistry child_registry_t;
390
391	void initFromParams(const Params&);
392
393	// textual artwork which menugl-imitators may want to match
394	static const std::string BOOLEAN_TRUE_PREFIX;
395	static const std::string BRANCH_SUFFIX;
396	static const std::string ARROW_UP;
397	static const std::string ARROW_DOWN;
398
399	// for scrollable menus
400	typedef enum e_scrolling_direction
401	{
402		SD_UP = 0,
403		SD_DOWN = 1,
404		SD_BEGIN = 2,
405		SD_END = 3
406	} EScrollingDirection;
407
408protected:
409	LLMenuGL(const LLMenuGL::Params& p);
410	friend class LLUICtrlFactory;
411	// let branching menu items use my protected traversal methods
412	friend class LLMenuItemBranchGL;
413public:
414	virtual ~LLMenuGL( void );
415
416	void parseChildXML(LLXMLNodePtr child, LLView* parent);
417
418	// LLView Functionality
419	/*virtual*/ BOOL handleUnicodeCharHere( llwchar uni_char );
420	/*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask );
421	/*virtual*/ BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
422	/*virtual*/ void draw( void );
423	/*virtual*/ void drawBackground(LLMenuItemGL* itemp, F32 alpha);
424	/*virtual*/ void setVisible(BOOL visible);
425	/*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);
426	/*virtual*/ void removeChild( LLView* ctrl);
427	/*virtual*/ BOOL postBuild();
428
429	virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
430
431	LLMenuGL* findChildMenuByName(const std::string& name, BOOL recurse) const;
432	
433	BOOL clearHoverItem();
434
435	// return the name label
436	const std::string& getLabel( void ) const { return mLabel.getString(); }
437	void setLabel(const LLStringExplicit& label) { mLabel = label; }
438
439	// background colors
440	void setBackgroundColor( const LLUIColor& color ) { mBackgroundColor = color; }
441	const LLUIColor& getBackgroundColor() const { return mBackgroundColor; }
442	void setBackgroundVisible( BOOL b )	{ mBgVisible = b; }
443	void setCanTearOff(BOOL tear_off);
444
445	// add a separator to this menu
446	virtual BOOL addSeparator();
447
448	// for branching menu items, bring sub menus up to root level of menu hierarchy
449	virtual void updateParent( LLView* parentp );
450
451	// setItemEnabled() - pass the name and the enable flag for a
452	// menu item. TRUE will make sure it's enabled, FALSE will disable
453	// it.
454	void setItemEnabled( const std::string& name, BOOL enable ); 
455	
456	// propagate message to submenus
457	void setEnabledSubMenus(BOOL enable);
458
459	void setItemVisible( const std::string& name, BOOL visible);
460	
461	// sets the left,bottom corner of menu, useful for popups
462	void setLeftAndBottom(S32 left, S32 bottom);
463
464	virtual BOOL handleJumpKey(KEY key);
465
466	virtual BOOL jumpKeysActive();
467
468	virtual BOOL isOpen();
469
470	void needsArrange() { mNeedsArrange = TRUE; }
471	// Shape this menu to fit the current state of the children, and
472	// adjust the child rects to fit. This is called automatically
473	// when you add items. *FIX: We may need to deal with visibility
474	// arrangement.
475	virtual void arrange( void );
476	void arrangeAndClear( void );
477
478	// remove all items on the menu
479	void empty( void );
480
481	void			setItemLastSelected(LLMenuItemGL* item);	// must be in menu
482	U32				getItemCount();				// number of menu items
483	LLMenuItemGL*	getItem(S32 number);		// 0 = first item
484	LLMenuItemGL*	getHighlightedItem();				
485
486	LLMenuItemGL*	highlightNextItem(LLMenuItemGL* cur_item, BOOL skip_disabled = TRUE);
487	LLMenuItemGL*	highlightPrevItem(LLMenuItemGL* cur_item, BOOL skip_disabled = TRUE);
488
489	void buildDrawLabels();
490	void createJumpKeys();
491
492	// Show popup at a specific location, in the spawn_view's coordinate frame
493	static void showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y);
494
495	// Whether to drop shadow menu bar 
496	void setDropShadowed( const BOOL shadowed );
497
498	void setParentMenuItem( LLMenuItemGL* parent_menu_item ) { mParentMenuItem = parent_menu_item->getHandle(); }
499	LLMenuItemGL* getParentMenuItem() const { return dynamic_cast<LLMenuItemGL*>(mParentMenuItem.get()); }
500
501	void setTornOff(BOOL torn_off);
502	BOOL getTornOff() { return mTornOff; }
503
504	BOOL getCanTearOff() { return mTearOffItem != NULL; }
505
506	KEY getJumpKey() const { return mJumpKey; }
507	void setJumpKey(KEY key) { mJumpKey = key; }
508
509	static void setKeyboardMode(BOOL mode) { sKeyboardMode = mode; }
510	static BOOL getKeyboardMode() { return sKeyboardMode; }
511
512	S32 getShortcutPad() { return mShortcutPad; }
513
514	bool scrollItems(EScrollingDirection direction);
515	BOOL isScrollable() const { return mScrollable; }
516
517	static class LLMenuHolderGL* sMenuContainer;
518	
519	void resetScrollPositionOnShow(bool reset_scroll_pos) { mResetScrollPositionOnShow = reset_scroll_pos; }
520	bool isScrollPositionOnShowReset() { return mResetScrollPositionOnShow; }
521
522protected:
523	void createSpilloverBranch();
524	void cleanupSpilloverBranch();
525	// Add the menu item to this menu.
526	virtual BOOL append( LLMenuItemGL* item );
527
528	// add a menu - this will create a cascading menu
529	virtual BOOL appendMenu( LLMenuGL* menu );
530
531	// TODO: create accessor methods for these?
532	typedef std::list< LLMenuItemGL* > item_list_t;
533	item_list_t mItems;
534	LLMenuItemGL*mFirstVisibleItem;
535	LLMenuItemGL *mArrowUpItem, *mArrowDownItem;
536
537	typedef std::map<KEY, LLMenuItemGL*> navigation_key_map_t;
538	navigation_key_map_t mJumpKeys;
539	S32				mLastMouseX;
540	S32				mLastMouseY;
541	S32				mMouseVelX;
542	S32				mMouseVelY;
543	U32				mMaxScrollableItems;
544	U32				mPreferredWidth;
545	BOOL			mHorizontalLayout;
546	BOOL			mScrollable;
547	BOOL			mKeepFixedSize;
548	BOOL			mNeedsArrange;
549
550private:
551
552
553	static LLColor4 sDefaultBackgroundColor;
554	static BOOL		sKeyboardMode;
555
556	LLUIColor		mBackgroundColor;
557	BOOL			mBgVisible;
558	LLHandle<LLView> mParentMenuItem;
559	LLUIString		mLabel;
560	BOOL mDropShadowed; 	//  Whether to drop shadow 
561	bool			mHasSelection;
562	LLFrameTimer	mFadeTimer;
563	LLTimer			mScrollItemsTimer;
564	BOOL			mTornOff;
565	class LLMenuItemTearOffGL* mTearOffItem;
566	class LLMenuItemBranchGL* mSpilloverBranch;
567	LLMenuGL*		mSpilloverMenu;
568	KEY				mJumpKey;
569	BOOL			mCreateJumpKeys;
570	S32				mShortcutPad;
571	bool			mResetScrollPositionOnShow;
572}; // end class LLMenuGL
573
574
575
576//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
577// Class LLMenuItemBranchGL
578//
579// The LLMenuItemBranchGL represents a menu item that has a
580// sub-menu. This is used to make cascading menus.
581//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
582
583class LLMenuItemBranchGL : public LLMenuItemGL
584{
585public:
586	struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>
587	{
588		Optional<LLMenuGL*>	branch;
589	};
590
591protected:
592	LLMenuItemBranchGL(const Params&);
593	friend class LLUICtrlFactory;
594public:
595	virtual ~LLMenuItemBranchGL();
596	
597	virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
598
599	virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
600
601	// check if we've used these accelerators already
602	virtual BOOL addToAcceleratorList(std::list <LLKeyBinding*> *listp);
603
604	// called to rebuild the draw label
605	virtual void buildDrawLabel( void );
606
607	virtual void onCommit( void );
608
609	virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
610	virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
611
612	// set the hover status (called by it's menu) and if the object is
613	// active. This is used for behavior transfer.
614	virtual void setHighlight( BOOL highlight );
615
616	virtual BOOL handleKeyHere(KEY key, MASK mask);
617
618	virtual BOOL isActive() const;
619
620	virtual BOOL isOpen() const;
621
622	LLMenuGL* getBranch() const { return (LLMenuGL*)mBranchHandle.get(); }
623
624	virtual void updateBranchParent( LLView* parentp );
625
626	// LLView Functionality
627	virtual void handleVisibilityChange( BOOL curVisibilityIn );
628
629	virtual void draw();
630
631	virtual void setEnabledSubMenus(BOOL enabled) { if (getBranch()) getBranch()->setEnabledSubMenus(enabled); }
632
633	virtual void openMenu();
634
635	virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE) const;
636	virtual LLView* findChildView(const std::string& name, BOOL recurse = TRUE) const;
637
638private:
639	LLHandle<LLView> mBranchHandle;
640}; // end class LLMenuItemBranchGL
641
642
643//-----------------------------------------------------------------------------
644// class LLContextMenu
645// A context menu
646//-----------------------------------------------------------------------------
647
648class LLContextMenu
649: public LLMenuGL
650{
651public:
652	struct Params : public LLInitParam::Block<Params, LLMenuGL::Params>
653	{
654		Params()
655		{
656			changeDefault(visible, false);
657		}
658	};
659
660protected:
661	LLContextMenu(const Params& p);
662	friend class LLUICtrlFactory;
663
664public:
665	virtual ~LLContextMenu() {}
666
667	// LLView Functionality
668	// can't set visibility directly, must call show or hide
669	virtual void	setVisible			(BOOL visible);
670	
671	virtual void	draw				();
672	
673	virtual void	show				(S32 x, S32 y);
674	virtual void	hide				();
675
676	virtual BOOL	handleHover			( S32 x, S32 y, MASK mask );
677	virtual BOOL	handleRightMouseDown( S32 x, S32 y, MASK mask );
678	virtual BOOL	handleRightMouseUp	( S32 x, S32 y, MASK mask );
679
680	virtual bool	addChild			(LLView* view, S32 tab_group = 0);
681
682			BOOL	appendContextSubMenu(LLContextMenu *menu);
683
684			LLHandle<LLContextMenu> getHandle() { return getDerivedHandle<LLContextMenu>(); }
685
686protected:
687	BOOL						mHoveredAnyItem;
688	LLMenuItemGL*				mHoverItem;
689	LLRootHandle<LLContextMenu>	mHandle;
690};
691
692
693
694//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
695// Class LLMenuBarGL
696//
697// A menu bar displays menus horizontally.
698//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
699
700class LLMenuBarGL : public LLMenuGL
701{
702public:
703	struct Params : public LLInitParam::Block<Params, LLMenuGL::Params>
704	{};
705	LLMenuBarGL( const Params& p );
706	virtual ~LLMenuBarGL();
707
708	/*virtual*/ BOOL handleAcceleratorKey(KEY key, MASK mask);
709	/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
710	/*virtual*/ BOOL handleJumpKey(KEY key);
711	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
712
713	/*virtual*/ void draw();
714	/*virtual*/ BOOL jumpKeysActive();
715
716	// add a vertical separator to this menu
717	virtual BOOL addSeparator();
718
719	// LLView Functionality
720	virtual BOOL handleHover( S32 x, S32 y, MASK mask );
721
722	// Returns x position of rightmost child, usually Help menu
723	S32 getRightmostMenuEdge();
724
725	void resetMenuTrigger() { mAltKeyTrigger = FALSE; }
726
727private:
728	// add a menu - this will create a drop down menu.
729	virtual BOOL appendMenu( LLMenuGL* menu );
730	// rearrange the child rects so they fit the shape of the menu
731	// bar.
732	virtual void arrange( void );
733
734	void checkMenuTrigger();
735
736	std::list <LLKeyBinding*>	mAccelerators;
737	BOOL						mAltKeyTrigger;
738};
739
740//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
741// Class LLMenuHolderGL
742//
743// High level view that serves as parent for all menus
744//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
745class LLMenuHolderGL : public LLPanel
746{
747public:
748	struct Params : public LLInitParam::Block<Params, LLPanel::Params>
749	{};
750	LLMenuHolderGL(const Params& p);
751	virtual ~LLMenuHolderGL() {}
752
753	virtual BOOL hideMenus();
754	void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
755	void setCanHide(BOOL can_hide) { mCanHide = can_hide; }
756
757	// LLView functionality
758	virtual void draw();
759	virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
760	virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
761
762	// Close context menus on right mouse up not handled by menus.
763	/*virtual*/ BOOL handleRightMouseUp( S32 x, S32 y, MASK mask );
764
765	virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
766	virtual const LLRect getMenuRect() const { return getLocalRect(); }
767	LLView*const getVisibleMenu() const;
768	virtual BOOL hasVisibleMenu() const {return getVisibleMenu() != NULL;}
769
770	static void setActivatedItem(LLMenuItemGL* item);
771
772	// Need to detect if mouse-up after context menu spawn has moved.
773	// If not, need to keep the menu up.
774	static LLCoordGL sContextMenuSpawnPos;
775
776private:
777	static LLHandle<LLView> sItemLastSelectedHandle;
778	static LLFrameTimer sItemActivationTimer;
779
780	BOOL mCanHide;
781};
782
783//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
784// Class LLTearOffMenu
785//
786// Floater that hosts a menu
787// https://wiki.lindenlab.com/mediawiki/index.php?title=LLTearOffMenu&oldid=81344
788//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
789class LLTearOffMenu : public LLFloater
790{
791public:
792	static LLTearOffMenu* create(LLMenuGL* menup);
793	virtual ~LLTearOffMenu();
794
795	virtual void draw(void);
796	virtual void onFocusReceived();
797	virtual void onFocusLost();
798	virtual BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
799	virtual BOOL handleKeyHere(KEY key, MASK mask);
800	virtual void translate(S32 x, S32 y);
801
802private:
803	LLTearOffMenu(LLMenuGL* menup);
804	
805	void closeTearOff();
806	
807	LLView*		mOldParent;
808	LLMenuGL*	mMenu;
809	F32			mTargetHeight;
810};
811
812//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
813// Class LLMenuItemTearOffGL
814//
815// This class represents a separator.
816//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
817
818class LLMenuItemTearOffGL : public LLMenuItemGL
819{
820public:
821	struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>
822	{};
823
824	LLMenuItemTearOffGL( const Params& );
825	
826	virtual void onCommit(void);
827	virtual void draw(void);
828	virtual U32 getNominalHeight() const;
829
830	LLFloater* getParentFloater();
831};
832
833
834// *TODO: this is currently working, so finish implementation
835class LLEditMenuHandlerMgr
836{
837public:
838	LLEditMenuHandlerMgr& getInstance() {
839		static LLEditMenuHandlerMgr instance;
840		return instance;
841	}
842	virtual ~LLEditMenuHandlerMgr() {}
843private:
844	LLEditMenuHandlerMgr() {};
845};
846
847
848// *TODO: Eliminate
849// For backwards compatability only; generally just use boost::bind
850class view_listener_t : public boost::signals2::trackable
851{
852public:
853	virtual bool handleEvent(const LLSD& userdata) = 0;
854	virtual ~view_listener_t() {}
855	
856	static void addEnable(view_listener_t* listener, const std::string& name)
857	{
858		LLUICtrl::EnableCallbackRegistry::currentRegistrar().add(name, boost::bind(&view_listener_t::handleEvent, listener, _2));
859	}
860	
861	static void addCommit(view_listener_t* listener, const std::string& name)
862	{
863		LLUICtrl::CommitCallbackRegistry::currentRegistrar().add(name, boost::bind(&view_listener_t::handleEvent, listener, _2));
864	}
865	
866	static void addMenu(view_listener_t* listener, const std::string& name)
867	{
868		// For now, add to both click and enable registries
869		addEnable(listener, name);
870		addCommit(listener, name);
871	}
872};
873
874#endif // LL_LLMENUGL_H