PageRenderTime 50ms CodeModel.GetById 5ms app.highlight 38ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llui/llview.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 731 lines | 478 code | 142 blank | 111 comment | 6 complexity | ea1a0c5570146bb8bdbcef763924667e MD5 | raw file
  1/** 
  2 * @file llview.h
  3 * @brief Container for other views, anything that draws.
  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_LLVIEW_H
 28#define LL_LLVIEW_H
 29
 30// A view is an area in a window that can draw.  It might represent
 31// the HUD or a dialog box or a button.  It can also contain sub-views
 32// and child widgets
 33
 34#include "stdtypes.h"
 35#include "llcoord.h"
 36#include "llfontgl.h"
 37#include "llhandle.h"
 38#include "llmortician.h"
 39#include "llmousehandler.h"
 40#include "llstring.h"
 41#include "llrect.h"
 42#include "llui.h"
 43#include "lluistring.h"
 44#include "llviewquery.h"
 45#include "stdenums.h"
 46#include "lluistring.h"
 47#include "llcursortypes.h"
 48#include "lluictrlfactory.h"
 49#include "lltreeiterators.h"
 50#include "llfocusmgr.h"
 51
 52#include <list>
 53#include <boost/function.hpp>
 54#include <boost/noncopyable.hpp>
 55
 56class LLSD;
 57
 58const U32	FOLLOWS_NONE	= 0x00;
 59const U32	FOLLOWS_LEFT	= 0x01;
 60const U32	FOLLOWS_RIGHT	= 0x02;
 61const U32	FOLLOWS_TOP		= 0x10;
 62const U32	FOLLOWS_BOTTOM	= 0x20;
 63const U32	FOLLOWS_ALL		= 0x33;
 64
 65const BOOL	MOUSE_OPAQUE = TRUE;
 66const BOOL	NOT_MOUSE_OPAQUE = FALSE;
 67
 68const U32 GL_NAME_UI_RESERVED = 2;
 69
 70
 71// maintains render state during traversal of UI tree
 72class LLViewDrawContext
 73{
 74public:
 75	F32 mAlpha;
 76
 77	LLViewDrawContext(F32 alpha = 1.f)
 78	:	mAlpha(alpha)
 79	{
 80		if (!sDrawContextStack.empty())
 81		{
 82			LLViewDrawContext* context_top = sDrawContextStack.back();
 83			// merge with top of stack
 84			mAlpha *= context_top->mAlpha;
 85		}
 86		sDrawContextStack.push_back(this);
 87	}
 88
 89	~LLViewDrawContext()
 90	{
 91		sDrawContextStack.pop_back();
 92	}
 93
 94	static const LLViewDrawContext& getCurrentContext();
 95
 96private:
 97	static std::vector<LLViewDrawContext*> sDrawContextStack;
 98};
 99
100class LLView 
101:	public LLMouseHandler,			// handles mouse events
102	public LLFocusableElement,		// handles keyboard events
103	public LLMortician,				// lazy deletion
104	public LLHandleProvider<LLView>	// passes out weak references to self
105{
106public:
107	struct Follows : public LLInitParam::ChoiceBlock<Follows>
108	{
109		Alternative<std::string>	string;
110		Alternative<U32>			flags;
111
112        Follows();
113	};
114
115	struct Params : public LLInitParam::Block<Params>
116	{
117		Mandatory<std::string>		name;
118
119		Optional<bool>				enabled,
120									visible,
121									mouse_opaque,
122									use_bounding_rect,
123									from_xui,
124									focus_root;
125
126		Optional<S32>				tab_group,
127									default_tab_group;
128		Optional<std::string>		tool_tip;
129
130		Optional<S32>				sound_flags;
131		Optional<Follows>			follows;
132		Optional<std::string>		hover_cursor;
133
134		Optional<std::string>		layout;
135		Optional<LLRect>			rect;
136
137		// Historical bottom-left layout used bottom_delta and left_delta
138		// for relative positioning.  New layout "topleft" prefers specifying
139		// based on top edge.
140		Optional<S32>				bottom_delta,	// from last bottom to my bottom
141									top_pad,		// from last bottom to my top
142									top_delta,		// from last top to my top
143									left_pad,		// from last right to my left
144									left_delta;		// from last left to my left
145
146		//FIXME: get parent context involved in parsing traversal
147		Ignored						needs_translate,	// cue for translation tools
148									xmlns,				// xml namespace
149									xmlns_xsi,			// xml namespace
150									xsi_schemaLocation,	// xml schema
151									xsi_type;			// xml schema type
152
153		Params();
154	};
155
156	// most widgets are valid children of LLView
157	typedef LLDefaultChildRegistry child_registry_t;
158
159	void initFromParams(const LLView::Params&);
160
161protected:
162	LLView(const LLView::Params&);
163	friend class LLUICtrlFactory;
164
165private:
166	// widgets in general are not copyable
167	LLView(const LLView& other) {};
168public:
169//#if LL_DEBUG
170	static BOOL sIsDrawing;
171//#endif
172	enum ESoundFlags
173	{
174		SILENT = 0,
175		MOUSE_DOWN = 1,
176		MOUSE_UP = 2
177	};
178
179	enum ESnapType
180	{
181		SNAP_PARENT,
182		SNAP_SIBLINGS,
183		SNAP_PARENT_AND_SIBLINGS
184	};
185
186	enum ESnapEdge
187	{
188		SNAP_LEFT, 
189		SNAP_TOP, 
190		SNAP_RIGHT, 
191		SNAP_BOTTOM
192	};
193
194	typedef std::list<LLView*> child_list_t;
195	typedef child_list_t::iterator					child_list_iter_t;
196	typedef child_list_t::const_iterator  			child_list_const_iter_t;
197	typedef child_list_t::reverse_iterator 			child_list_reverse_iter_t;
198	typedef child_list_t::const_reverse_iterator 	child_list_const_reverse_iter_t;
199
200	typedef std::vector<class LLUICtrl *>				ctrl_list_t;
201
202	typedef std::pair<S32, S32>							tab_order_t;
203	typedef std::pair<LLUICtrl *, tab_order_t>			tab_order_pair_t;
204	// this structure primarily sorts by the tab group, secondarily by the insertion ordinal (lastly by the value of the pointer)
205	typedef std::map<const LLUICtrl*, tab_order_t>		child_tab_order_t;
206	typedef child_tab_order_t::iterator					child_tab_order_iter_t;
207	typedef child_tab_order_t::const_iterator			child_tab_order_const_iter_t;
208	typedef child_tab_order_t::reverse_iterator			child_tab_order_reverse_iter_t;
209	typedef child_tab_order_t::const_reverse_iterator	child_tab_order_const_reverse_iter_t;
210
211	virtual ~LLView();
212
213	// Some UI widgets need to be added as controls.  Others need to
214	// be added as regular view children.  isCtrl should return TRUE
215	// if a widget needs to be added as a ctrl
216	virtual BOOL isCtrl() const;
217
218	virtual BOOL isPanel() const;
219	
220	//
221	// MANIPULATORS
222	//
223	void		setMouseOpaque( BOOL b )		{ mMouseOpaque = b; }
224	BOOL		getMouseOpaque() const			{ return mMouseOpaque; }
225	void		setToolTip( const LLStringExplicit& msg );
226	BOOL		setToolTipArg( const LLStringExplicit& key, const LLStringExplicit& text );
227	void		setToolTipArgs( const LLStringUtil::format_map_t& args );
228
229	virtual void setRect(const LLRect &rect);
230	void		setFollows(U32 flags)			{ mReshapeFlags = flags; }
231
232	// deprecated, use setFollows() with FOLLOWS_LEFT | FOLLOWS_TOP, etc.
233	void		setFollowsNone()				{ mReshapeFlags = FOLLOWS_NONE; }
234	void		setFollowsLeft()				{ mReshapeFlags |= FOLLOWS_LEFT; }
235	void		setFollowsTop()					{ mReshapeFlags |= FOLLOWS_TOP; }
236	void		setFollowsRight()				{ mReshapeFlags |= FOLLOWS_RIGHT; }
237	void		setFollowsBottom()				{ mReshapeFlags |= FOLLOWS_BOTTOM; }
238	void		setFollowsAll()					{ mReshapeFlags |= FOLLOWS_ALL; }
239
240	void        setSoundFlags(U8 flags)			{ mSoundFlags = flags; }
241	void		setName(std::string name)			{ mName = name; }
242	void		setUseBoundingRect( BOOL use_bounding_rect );
243	BOOL		getUseBoundingRect() const;
244
245	ECursorType	getHoverCursor() { return mHoverCursor; }
246
247	virtual const std::string getToolTip() const			{ return mToolTipMsg.getString(); }
248
249	void		sendChildToFront(LLView* child);
250	void		sendChildToBack(LLView* child);
251	void		moveChildToFrontOfTabGroup(LLUICtrl* child);
252	void		moveChildToBackOfTabGroup(LLUICtrl* child);
253	
254	virtual bool addChild(LLView* view, S32 tab_group = 0);
255
256	// implemented in terms of addChild()
257	bool		addChildInBack(LLView* view,  S32 tab_group = 0);
258
259	// remove the specified child from the view, and set it's parent to NULL.
260	virtual void	removeChild(LLView* view);
261
262	virtual BOOL	postBuild() { return TRUE; }
263
264	const child_tab_order_t& getCtrlOrder() const		{ return mCtrlOrder; }
265	ctrl_list_t getCtrlList() const;
266	ctrl_list_t getCtrlListSorted() const;
267	
268	void setDefaultTabGroup(S32 d)				{ mDefaultTabGroup = d; }
269	S32 getDefaultTabGroup() const				{ return mDefaultTabGroup; }
270	S32 getLastTabGroup()						{ return mLastTabGroup; }
271
272	BOOL		isInVisibleChain() const;
273	BOOL		isInEnabledChain() const;
274
275	void		setFocusRoot(BOOL b)			{ mIsFocusRoot = b; }
276	BOOL		isFocusRoot() const				{ return mIsFocusRoot; }
277	virtual BOOL canFocusChildren() const;
278
279	BOOL focusNextRoot();
280	BOOL focusPrevRoot();
281
282	// Normally we want the app menus to get priority on accelerated keys
283	// However, sometimes we want to give specific views a first chance
284	// iat handling them. (eg. the script editor)
285	virtual bool	hasAccelerators() const { return false; };
286
287	// delete all children. Override this function if you need to
288	// perform any extra clean up such as cached pointers to selected
289	// children, etc.
290	virtual void deleteAllChildren();
291
292	void 	setAllChildrenEnabled(BOOL b);
293
294	virtual void	setVisible(BOOL visible);
295	const BOOL&		getVisible() const			{ return mVisible; }
296	virtual void	setEnabled(BOOL enabled);
297	BOOL			getEnabled() const			{ return mEnabled; }
298	/// 'available' in this context means 'visible and enabled': in other
299	/// words, can a user actually interact with this?
300	virtual bool	isAvailable() const;
301	/// The static isAvailable() tests an LLView* that could be NULL.
302	static bool		isAvailable(const LLView* view);
303	U8              getSoundFlags() const       { return mSoundFlags; }
304
305	virtual BOOL	setLabelArg( const std::string& key, const LLStringExplicit& text );
306
307	virtual void	handleVisibilityChange ( BOOL new_visibility );
308
309	void			pushVisible(BOOL visible)	{ mLastVisible = mVisible; setVisible(visible); }
310	void			popVisible()				{ setVisible(mLastVisible); }
311	BOOL			getLastVisible()	const	{ return mLastVisible; }
312
313	U32			getFollows() const				{ return mReshapeFlags; }
314	BOOL		followsLeft() const				{ return mReshapeFlags & FOLLOWS_LEFT; }
315	BOOL		followsRight() const			{ return mReshapeFlags & FOLLOWS_RIGHT; }
316	BOOL		followsTop() const				{ return mReshapeFlags & FOLLOWS_TOP; }
317	BOOL		followsBottom() const			{ return mReshapeFlags & FOLLOWS_BOTTOM; }
318	BOOL		followsAll() const				{ return mReshapeFlags & FOLLOWS_ALL; }
319
320	const LLRect&	getRect() const				{ return mRect; }
321	const LLRect&	getBoundingRect() const		{ return mBoundingRect; }
322	LLRect	getLocalBoundingRect() const;
323	LLRect	calcScreenRect() const;
324	LLRect	calcScreenBoundingRect() const;
325	LLRect	getLocalRect() const;
326	virtual LLRect getSnapRect() const;
327	LLRect getLocalSnapRect() const;
328
329	std::string getLayout() { return mLayout; }
330
331	// Override and return required size for this object. 0 for width/height means don't care.
332	virtual LLRect getRequiredRect();
333	LLRect calcBoundingRect();
334	void updateBoundingRect();
335
336	LLView*		getRootView();
337	LLView*		getParent() const				{ return mParentView; }
338	LLView*		getFirstChild() const			{ return (mChildList.empty()) ? NULL : *(mChildList.begin()); }
339	LLView*		findPrevSibling(LLView* child);
340	LLView*		findNextSibling(LLView* child);
341	S32			getChildCount()	const			{ return (S32)mChildList.size(); }
342	template<class _Pr3> void sortChildren(_Pr3 _Pred) { mChildList.sort(_Pred); }
343	BOOL		hasAncestor(const LLView* parentp) const;
344	BOOL		hasChild(const std::string& childname, BOOL recurse = FALSE) const;
345	BOOL 		childHasKeyboardFocus( const std::string& childname ) const;
346	
347	// these iterators are used for collapsing various tree traversals into for loops
348	typedef LLTreeDFSIter<LLView, child_list_const_iter_t> tree_iterator_t;
349	tree_iterator_t beginTreeDFS();
350	tree_iterator_t endTreeDFS();
351
352	typedef LLTreeDFSPostIter<LLView, child_list_const_iter_t> tree_post_iterator_t;
353	tree_post_iterator_t beginTreeDFSPost();
354	tree_post_iterator_t endTreeDFSPost();
355
356	typedef LLTreeBFSIter<LLView, child_list_const_iter_t> bfs_tree_iterator_t;
357	bfs_tree_iterator_t beginTreeBFS();
358	bfs_tree_iterator_t endTreeBFS();
359
360
361	typedef LLTreeDownIter<LLView> root_to_view_iterator_t;
362	root_to_view_iterator_t beginRootToView();
363	root_to_view_iterator_t endRootToView();
364
365	//
366	// UTILITIES
367	//
368
369	// Default behavior is to use reshape flags to resize child views
370	virtual void	reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
371	virtual void	translate( S32 x, S32 y );
372	void			setOrigin( S32 x, S32 y )	{ mRect.translate( x - mRect.mLeft, y - mRect.mBottom ); }
373	BOOL			translateIntoRect( const LLRect& constraint, BOOL allow_partial_outside );
374	BOOL			translateIntoRectWithExclusion( const LLRect& inside, const LLRect& exclude, BOOL allow_partial_outside );
375	void			centerWithin(const LLRect& bounds);
376
377	void	setShape(const LLRect& new_rect, bool by_user = false);
378	virtual LLView*	findSnapRect(LLRect& new_rect, const LLCoordGL& mouse_dir, LLView::ESnapType snap_type, S32 threshold, S32 padding = 0);
379	virtual LLView*	findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding = 0);
380	virtual BOOL	canSnapTo(const LLView* other_view);
381	virtual void	setSnappedTo(const LLView* snap_view);
382
383	// inherited from LLFocusableElement
384	/* virtual */ BOOL	handleKey(KEY key, MASK mask, BOOL called_from_parent);
385	/* virtual */ BOOL	handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
386
387	virtual BOOL	handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
388									  EDragAndDropType cargo_type,
389									  void* cargo_data,
390									  EAcceptance* accept,
391									  std::string& tooltip_msg);
392
393	virtual void	draw();
394
395	void parseFollowsFlags(const LLView::Params& params);
396
397	// Some widgets, like close box buttons, don't need to be saved
398	BOOL getFromXUI() const { return mFromXUI; }
399	void setFromXUI(BOOL b) { mFromXUI = b; }
400
401	typedef enum e_hit_test_type
402	{
403		HIT_TEST_USE_BOUNDING_RECT,
404		HIT_TEST_IGNORE_BOUNDING_RECT
405	}EHitTestType;
406
407	BOOL parentPointInView(S32 x, S32 y, EHitTestType type = HIT_TEST_USE_BOUNDING_RECT) const;
408	BOOL pointInView(S32 x, S32 y, EHitTestType type = HIT_TEST_USE_BOUNDING_RECT) const;
409	BOOL blockMouseEvent(S32 x, S32 y) const;
410
411	// See LLMouseHandler virtuals for screenPointToLocal and localPointToScreen
412	BOOL localPointToOtherView( S32 x, S32 y, S32 *other_x, S32 *other_y, const LLView* other_view) const;
413	BOOL localRectToOtherView( const LLRect& local, LLRect* other, const LLView* other_view ) const;
414	void screenRectToLocal( const LLRect& screen, LLRect* local ) const;
415	void localRectToScreen( const LLRect& local, LLRect* screen ) const;
416	
417	LLControlVariable *findControl(const std::string& name);
418
419	const child_list_t*	getChildList() const { return &mChildList; }
420	child_list_const_iter_t	beginChild() const { return mChildList.begin(); }
421	child_list_const_iter_t	endChild() const { return mChildList.end(); }
422
423	// LLMouseHandler functions
424	//  Default behavior is to pass events to children
425	/*virtual*/ BOOL	handleHover(S32 x, S32 y, MASK mask);
426	/*virtual*/ BOOL	handleMouseUp(S32 x, S32 y, MASK mask);
427	/*virtual*/ BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
428	/*virtual*/ BOOL	handleMiddleMouseUp(S32 x, S32 y, MASK mask);
429	/*virtual*/ BOOL	handleMiddleMouseDown(S32 x, S32 y, MASK mask);
430	/*virtual*/ BOOL	handleDoubleClick(S32 x, S32 y, MASK mask);
431	/*virtual*/ BOOL	handleScrollWheel(S32 x, S32 y, S32 clicks);
432	/*virtual*/ BOOL	handleRightMouseDown(S32 x, S32 y, MASK mask);
433	/*virtual*/ BOOL	handleRightMouseUp(S32 x, S32 y, MASK mask);	
434	/*virtual*/ BOOL	handleToolTip(S32 x, S32 y, MASK mask);
435
436	/*virtual*/ const std::string& getName() const;
437	/*virtual*/ void	onMouseCaptureLost();
438	/*virtual*/ BOOL	hasMouseCapture();
439	/*virtual*/ void	screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const;
440	/*virtual*/ void	localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const;
441
442	virtual		LLView*	childFromPoint(S32 x, S32 y, bool recur=false);
443
444	// view-specific handlers 
445	virtual void	onMouseEnter(S32 x, S32 y, MASK mask);
446	virtual void	onMouseLeave(S32 x, S32 y, MASK mask);
447
448	std::string getPathname() const;
449	// static method handles NULL pointer too
450	static std::string getPathname(const LLView*);
451
452	template <class T> T* findChild(const std::string& name, BOOL recurse = TRUE) const
453	{
454		LLView* child = findChildView(name, recurse);
455		T* result = dynamic_cast<T*>(child);
456		return result;
457	}
458
459	template <class T> T* getChild(const std::string& name, BOOL recurse = TRUE) const;
460
461	template <class T> T& getChildRef(const std::string& name, BOOL recurse = TRUE) const
462	{
463		return *getChild<T>(name, recurse);
464	}
465
466	virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE) const;
467	virtual LLView* findChildView(const std::string& name, BOOL recurse = TRUE) const;
468
469	template <class T> T* getDefaultWidget(const std::string& name) const
470	{
471		LLView* widgetp = getDefaultWidgetContainer().findChildView(name);
472		return dynamic_cast<T*>(widgetp);
473	}
474
475	template <class T> T* getParentByType() const
476	{
477		LLView* parent = getParent();
478		while(parent)
479		{
480			if (dynamic_cast<T*>(parent))
481			{
482				return static_cast<T*>(parent);
483			}
484			parent = parent->getParent();
485		}
486		return NULL;
487	}
488
489	//////////////////////////////////////////////
490	// statics
491	//////////////////////////////////////////////
492	//static LLFontGL::HAlign selectFontHAlign(LLXMLNodePtr node);
493	
494	// focuses the item in the list after the currently-focused item, wrapping if necessary
495	static	BOOL focusNext(LLView::child_list_t & result);
496	// focuses the item in the list before the currently-focused item, wrapping if necessary
497	static	BOOL focusPrev(LLView::child_list_t & result);
498
499	// returns query for iterating over controls in tab order	
500	static const LLCtrlQuery & getTabOrderQuery();
501	// return query for iterating over focus roots in tab order
502	static const LLCtrlQuery & getFocusRootsQuery();
503
504	static LLWindow*	getWindow(void) { return LLUI::sWindow; }
505
506	// Set up params after XML load before calling new(),
507	// usually to adjust layout.
508	static void applyXUILayout(Params& p, LLView* parent);
509
510	// For re-export of floaters and panels, convert the coordinate system
511	// to be top-left based.
512	static void setupParamsForExport(Params& p, LLView* parent);
513	
514	//virtual BOOL	addChildFromParam(const LLInitParam::BaseBlock& params) { return TRUE; }
515	virtual BOOL	handleKeyHere(KEY key, MASK mask);
516	virtual BOOL	handleUnicodeCharHere(llwchar uni_char);
517
518	virtual void	handleReshape(const LLRect& rect, bool by_user);
519	virtual void	dirtyRect();
520
521	//send custom notification to LLView parent
522	virtual S32	notifyParent(const LLSD& info);
523
524	//send custom notification to all view childrend
525	// return true if _any_ children return true. otherwise false.
526	virtual bool	notifyChildren(const LLSD& info);
527
528	//send custom notification to current view
529	virtual S32	notify(const LLSD& info) { return 0;};
530
531	static const LLViewDrawContext& getDrawContext();
532	
533	// Returns useful information about this ui widget.
534	LLSD getInfo(void);
535
536protected:
537	void			drawDebugRect();
538	void			drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, BOOL force_draw = FALSE);
539	void			drawChildren();
540	bool			visibleAndContains(S32 local_x, S32 local_Y);
541	bool			visibleEnabledAndContains(S32 local_x, S32 local_y);
542	void			logMouseEvent();
543
544	LLView*	childrenHandleKey(KEY key, MASK mask);
545	LLView* childrenHandleUnicodeChar(llwchar uni_char);
546	LLView*	childrenHandleDragAndDrop(S32 x, S32 y, MASK mask,
547											  BOOL drop,
548											  EDragAndDropType type,
549											  void* data,
550											  EAcceptance* accept,
551											  std::string& tooltip_msg);
552
553	LLView*	childrenHandleHover(S32 x, S32 y, MASK mask);
554	LLView* childrenHandleMouseUp(S32 x, S32 y, MASK mask);
555	LLView* childrenHandleMouseDown(S32 x, S32 y, MASK mask);
556	LLView* childrenHandleMiddleMouseUp(S32 x, S32 y, MASK mask);
557	LLView* childrenHandleMiddleMouseDown(S32 x, S32 y, MASK mask);
558	LLView* childrenHandleDoubleClick(S32 x, S32 y, MASK mask);
559	LLView*	childrenHandleScrollWheel(S32 x, S32 y, S32 clicks);
560	LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask);
561	LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask);
562	LLView* childrenHandleToolTip(S32 x, S32 y, MASK mask);
563
564	ECursorType mHoverCursor;
565
566	virtual void addInfo(LLSD & info);
567private:
568
569	template <typename METHOD, typename XDATA>
570	LLView* childrenHandleMouseEvent(const METHOD& method, S32 x, S32 y, XDATA extra, bool allow_mouse_block = true);
571
572	template <typename METHOD, typename CHARTYPE>
573	LLView* childrenHandleCharEvent(const std::string& desc, const METHOD& method,
574									CHARTYPE c, MASK mask);
575
576	// adapter to blur distinction between handleKey() and handleUnicodeChar()
577	// for childrenHandleCharEvent()
578	BOOL	handleUnicodeCharWithDummyMask(llwchar uni_char, MASK /* dummy */, BOOL from_parent)
579	{
580		return handleUnicodeChar(uni_char, from_parent);
581	}
582
583	LLView*		mParentView;
584	child_list_t mChildList;
585
586	// location in pixels, relative to surrounding structure, bottom,left=0,0
587	BOOL		mVisible;
588	LLRect		mRect;
589	LLRect		mBoundingRect;
590	
591	std::string mLayout;
592	std::string	mName;
593	
594	U32			mReshapeFlags;
595
596	child_tab_order_t mCtrlOrder;
597	S32			mDefaultTabGroup;
598	S32			mLastTabGroup;
599
600	BOOL		mEnabled;		// Enabled means "accepts input that has an effect on the state of the application."
601								// A disabled view, for example, may still have a scrollbar that responds to mouse events.
602	BOOL		mMouseOpaque;	// Opaque views handle all mouse events that are over their rect.
603	LLUIString	mToolTipMsg;	// isNull() is true if none.
604
605	U8          mSoundFlags;
606	BOOL		mFromXUI;
607
608	BOOL		mIsFocusRoot;
609	BOOL		mUseBoundingRect; // hit test against bounding rectangle that includes all child elements
610
611	BOOL		mLastVisible;
612
613	S32			mNextInsertionOrdinal;
614
615	bool		mInDraw;
616
617	static LLWindow* sWindow;	// All root views must know about their window.
618
619	typedef std::map<std::string, LLView*> default_widget_map_t;
620	// allocate this map no demand, as it is rarely needed
621	mutable LLView* mDefaultWidgets;
622
623	LLView& getDefaultWidgetContainer() const;
624
625	// This allows special mouse-event targeting logic for testing.
626	typedef boost::function<bool(const LLView*, S32 x, S32 y)> DrilldownFunc;
627	static DrilldownFunc sDrilldown;
628
629public:
630	// This is the only public accessor to alter sDrilldown. This is not
631	// an accident. The intended usage pattern is like:
632	// {
633	//     LLView::TemporaryDrilldownFunc scoped_func(myfunctor);
634	//     // ... test with myfunctor ...
635	// } // exiting block restores original LLView::sDrilldown
636	class TemporaryDrilldownFunc: public boost::noncopyable
637	{
638	public:
639		TemporaryDrilldownFunc(const DrilldownFunc& func):
640			mOldDrilldown(sDrilldown)
641		{
642			sDrilldown = func;
643		}
644
645		~TemporaryDrilldownFunc()
646		{
647			sDrilldown = mOldDrilldown;
648		}
649
650	private:
651		DrilldownFunc mOldDrilldown;
652	};
653
654	// Depth in view hierarchy during rendering
655	static S32	sDepth;
656
657	// Draw debug rectangles around widgets to help with alignment and spacing
658	static bool	sDebugRects;
659
660	// Draw widget names and sizes when drawing debug rectangles, turning this
661	// off is useful to make the rectangles themselves easier to see.
662	static bool sDebugRectsShowNames;
663
664	static bool sDebugKeys;
665	static bool sDebugMouseHandling;
666	static std::string sMouseHandlerMessage;
667	static S32	sSelectID;
668	static std::set<LLView*> sPreviewHighlightedElements;	// DEV-16869
669	static BOOL sHighlightingDiffs;							// DEV-16869
670	static LLView* sPreviewClickedElement;					// DEV-16869
671	static BOOL sDrawPreviewHighlights;
672	static S32 sLastLeftXML;
673	static S32 sLastBottomXML;
674	static BOOL sForceReshape;
675};
676
677class LLCompareByTabOrder
678{
679public:
680	LLCompareByTabOrder(const LLView::child_tab_order_t& order) : mTabOrder(order) {}
681	virtual ~LLCompareByTabOrder() {}
682	bool operator() (const LLView* const a, const LLView* const b) const;
683private:
684	virtual bool compareTabOrders(const LLView::tab_order_t & a, const LLView::tab_order_t & b) const { return a < b; }
685	// ok to store a reference, as this should only be allocated on stack during view query operations
686	const LLView::child_tab_order_t& mTabOrder;
687};
688
689template <class T> T* LLView::getChild(const std::string& name, BOOL recurse) const
690{
691	LLView* child = findChildView(name, recurse);
692	T* result = dynamic_cast<T*>(child);
693	if (!result)
694	{
695		// did we find *something* with that name?
696		if (child)
697		{
698			llwarns << "Found child named \"" << name << "\" but of wrong type " << typeid(*child).name() << ", expecting " << typeid(T*).name() << llendl;
699		}
700		result = getDefaultWidget<T>(name);
701		if (!result)
702		{
703			result = LLUICtrlFactory::getDefaultWidget<T>(name);
704
705			if (result)
706			{
707				// *NOTE: You cannot call mFoo = getChild<LLFoo>("bar")
708				// in a floater or panel constructor.  The widgets will not
709				// be ready.  Instead, put it in postBuild().
710				llwarns << "Making dummy " << typeid(T).name() << " named \"" << name << "\" in " << getName() << llendl;
711			}
712			else
713			{
714				llwarns << "Failed to create dummy " << typeid(T).name() << llendl;
715				return NULL;
716			}
717
718			getDefaultWidgetContainer().addChild(result);
719		}
720	}
721	return result;
722}
723
724// Compiler optimization - don't generate these specializations inline,
725// require explicit specialization.  See llbutton.cpp for an example.
726#ifndef LLVIEW_CPP
727extern template class LLView* LLView::getChild<class LLView>(
728	const std::string& name, BOOL recurse) const;
729#endif
730
731#endif //LL_LLVIEW_H