diff options
Diffstat (limited to 'indra/llui/llview.h')
-rw-r--r-- | indra/llui/llview.h | 1474 |
1 files changed, 737 insertions, 737 deletions
diff --git a/indra/llui/llview.h b/indra/llui/llview.h index ddb0a3dbbf..3af748dda6 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -1,737 +1,737 @@ -/**
- * @file llview.h
- * @brief Container for other views, anything that draws.
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLVIEW_H
-#define LL_LLVIEW_H
-
-// A view is an area in a window that can draw. It might represent
-// the HUD or a dialog box or a button. It can also contain sub-views
-// and child widgets
-
-#include "stdtypes.h"
-#include "llcoord.h"
-#include "llfontgl.h"
-#include "llhandle.h"
-#include "llmortician.h"
-#include "llmousehandler.h"
-#include "llstring.h"
-#include "llrect.h"
-#include "llui.h"
-#include "lluistring.h"
-#include "llviewquery.h"
-#include "lluistring.h"
-#include "llcursortypes.h"
-#include "lluictrlfactory.h"
-#include "lltreeiterators.h"
-#include "llfocusmgr.h"
-
-#include <list>
-#include <boost/function.hpp>
-#include <boost/noncopyable.hpp>
-
-class LLSD;
-
-const U32 FOLLOWS_NONE = 0x00;
-const U32 FOLLOWS_LEFT = 0x01;
-const U32 FOLLOWS_RIGHT = 0x02;
-const U32 FOLLOWS_TOP = 0x10;
-const U32 FOLLOWS_BOTTOM = 0x20;
-const U32 FOLLOWS_ALL = 0x33;
-
-const bool MOUSE_OPAQUE = true;
-const bool NOT_MOUSE_OPAQUE = false;
-
-const U32 GL_NAME_UI_RESERVED = 2;
-
-
-// maintains render state during traversal of UI tree
-class LLViewDrawContext
-{
-public:
- F32 mAlpha;
-
- LLViewDrawContext(F32 alpha = 1.f)
- : mAlpha(alpha)
- {
- if (!sDrawContextStack.empty())
- {
- LLViewDrawContext* context_top = sDrawContextStack.back();
- // merge with top of stack
- mAlpha *= context_top->mAlpha;
- }
- sDrawContextStack.push_back(this);
- }
-
- ~LLViewDrawContext()
- {
- sDrawContextStack.pop_back();
- }
-
- static const LLViewDrawContext& getCurrentContext();
-
-private:
- static std::vector<LLViewDrawContext*> sDrawContextStack;
-};
-
-class LLView
-: public LLMouseHandler, // handles mouse events
- public LLFocusableElement, // handles keyboard events
- public LLMortician, // lazy deletion
- public LLHandleProvider<LLView> // passes out weak references to self
-{
-public:
-
- enum EOrientation { HORIZONTAL, VERTICAL, ORIENTATION_COUNT };
-
- struct Follows : public LLInitParam::ChoiceBlock<Follows>
- {
- Alternative<std::string> string;
- Alternative<U32> flags;
-
- Follows();
- };
-
- struct Params : public LLInitParam::Block<Params>
- {
- Mandatory<std::string> name;
-
- Optional<bool> enabled,
- visible,
- mouse_opaque,
- use_bounding_rect,
- from_xui,
- focus_root;
-
- Optional<S32> tab_group,
- default_tab_group;
- Optional<std::string> tool_tip;
-
- Optional<S32> sound_flags;
- Optional<Follows> follows;
- Optional<std::string> hover_cursor;
-
- Optional<std::string> layout;
- Optional<LLRect> rect;
-
- // Historical bottom-left layout used bottom_delta and left_delta
- // for relative positioning. New layout "topleft" prefers specifying
- // based on top edge.
- Optional<S32> bottom_delta, // from last bottom to my bottom
- top_pad, // from last bottom to my top
- top_delta, // from last top to my top
- left_pad, // from last right to my left
- left_delta; // from last left to my left
-
- //FIXME: get parent context involved in parsing traversal
- Ignored needs_translate, // cue for translation tools
- xmlns, // xml namespace
- xmlns_xsi, // xml namespace
- xsi_schemaLocation, // xml schema
- xsi_type; // xml schema type
-
- Params();
- };
-
- // most widgets are valid children of LLView
- typedef LLDefaultChildRegistry child_registry_t;
-
- void initFromParams(const LLView::Params&);
-
-protected:
- LLView(const LLView::Params&);
- friend class LLUICtrlFactory;
-
-private:
- // widgets in general are not copyable
- LLView(const LLView& other);
-public:
-//#if LL_DEBUG
- static bool sIsDrawing;
-//#endif
- enum ESoundFlags
- {
- SILENT = 0,
- MOUSE_DOWN = 1,
- MOUSE_UP = 2
- };
-
- enum ESnapType
- {
- SNAP_PARENT,
- SNAP_SIBLINGS,
- SNAP_PARENT_AND_SIBLINGS
- };
-
- enum ESnapEdge
- {
- SNAP_LEFT,
- SNAP_TOP,
- SNAP_RIGHT,
- SNAP_BOTTOM
- };
-
- typedef std::list<LLView*> child_list_t;
- typedef child_list_t::iterator child_list_iter_t;
- typedef child_list_t::const_iterator child_list_const_iter_t;
- typedef child_list_t::reverse_iterator child_list_reverse_iter_t;
- typedef child_list_t::const_reverse_iterator child_list_const_reverse_iter_t;
-
- typedef std::pair<LLView *, S32> tab_order_pair_t;
- // this structure primarily sorts by the tab group, secondarily by the insertion ordinal (lastly by the value of the pointer)
- typedef std::map<const LLView*, S32> child_tab_order_t;
- typedef child_tab_order_t::iterator child_tab_order_iter_t;
- typedef child_tab_order_t::const_iterator child_tab_order_const_iter_t;
- typedef child_tab_order_t::reverse_iterator child_tab_order_reverse_iter_t;
- typedef child_tab_order_t::const_reverse_iterator child_tab_order_const_reverse_iter_t;
-
- virtual ~LLView();
-
- // Some UI widgets need to be added as controls. Others need to
- // be added as regular view children. isCtrl should return true
- // if a widget needs to be added as a ctrl
- virtual bool isCtrl() const;
-
- virtual bool isPanel() const;
-
- //
- // MANIPULATORS
- //
- void setMouseOpaque( bool b ) { mMouseOpaque = b; }
- bool getMouseOpaque() const { return mMouseOpaque; }
- void setToolTip( const LLStringExplicit& msg );
- bool setToolTipArg( const LLStringExplicit& key, const LLStringExplicit& text );
- void setToolTipArgs( const LLStringUtil::format_map_t& args );
-
- virtual void setRect(const LLRect &rect);
- void setFollows(U32 flags) { mReshapeFlags = flags; }
-
- // deprecated, use setFollows() with FOLLOWS_LEFT | FOLLOWS_TOP, etc.
- void setFollowsNone() { mReshapeFlags = FOLLOWS_NONE; }
- void setFollowsLeft() { mReshapeFlags |= FOLLOWS_LEFT; }
- void setFollowsTop() { mReshapeFlags |= FOLLOWS_TOP; }
- void setFollowsRight() { mReshapeFlags |= FOLLOWS_RIGHT; }
- void setFollowsBottom() { mReshapeFlags |= FOLLOWS_BOTTOM; }
- void setFollowsAll() { mReshapeFlags |= FOLLOWS_ALL; }
-
- void setSoundFlags(U8 flags) { mSoundFlags = flags; }
- void setName(std::string name) { mName = name; }
- void setUseBoundingRect( bool use_bounding_rect );
- bool getUseBoundingRect() const;
-
- ECursorType getHoverCursor() { return mHoverCursor; }
-
- static F32 getTooltipTimeout();
- virtual const std::string getToolTip() const;
- virtual const std::string& getText() const { return LLStringUtil::null; }
- virtual const LLFontGL* getFont() const { return nullptr; }
-
- void sendChildToFront(LLView* child);
- void sendChildToBack(LLView* child);
-
- virtual bool addChild(LLView* view, S32 tab_group = 0);
-
- // implemented in terms of addChild()
- bool addChildInBack(LLView* view, S32 tab_group = 0);
-
- // remove the specified child from the view, and set it's parent to NULL.
- virtual void removeChild(LLView* view);
-
- virtual bool postBuild() { return true; }
-
- const child_tab_order_t& getTabOrder() const { return mTabOrder; }
-
- void setDefaultTabGroup(S32 d) { mDefaultTabGroup = d; }
- S32 getDefaultTabGroup() const { return mDefaultTabGroup; }
- S32 getLastTabGroup() { return mLastTabGroup; }
-
- bool isInVisibleChain() const;
- bool isInEnabledChain() const;
-
- void setFocusRoot(bool b) { mIsFocusRoot = b; }
- bool isFocusRoot() const { return mIsFocusRoot; }
- virtual bool canFocusChildren() const;
-
- bool focusNextRoot();
- bool focusPrevRoot();
-
- // Normally we want the app menus to get priority on accelerated keys
- // However, sometimes we want to give specific views a first chance
- // iat handling them. (eg. the script editor)
- virtual bool hasAccelerators() const { return false; };
-
- // delete all children. Override this function if you need to
- // perform any extra clean up such as cached pointers to selected
- // children, etc.
- virtual void deleteAllChildren();
-
- void setAllChildrenEnabled(bool b);
-
- virtual void setVisible(bool visible);
- void setVisibleDirect(bool visible) { mVisible = visible; }
- const bool& getVisible() const { return mVisible; }
- virtual void setEnabled(bool enabled);
- bool getEnabled() const { return mEnabled; }
- /// 'available' in this context means 'visible and enabled': in other
- /// words, can a user actually interact with this?
- virtual bool isAvailable() const;
- /// The static isAvailable() tests an LLView* that could be NULL.
- static bool isAvailable(const LLView* view);
- U8 getSoundFlags() const { return mSoundFlags; }
-
- virtual bool setLabelArg( const std::string& key, const LLStringExplicit& text );
-
- virtual void onVisibilityChange ( bool new_visibility );
- virtual void onUpdateScrollToChild(const LLUICtrl * cntrl);
-
- void pushVisible(bool visible) { mLastVisible = mVisible; setVisible(visible); }
- void popVisible() { setVisible(mLastVisible); }
- bool getLastVisible() const { return mLastVisible; }
-
- U32 getFollows() const { return mReshapeFlags; }
- bool followsLeft() const { return mReshapeFlags & FOLLOWS_LEFT; }
- bool followsRight() const { return mReshapeFlags & FOLLOWS_RIGHT; }
- bool followsTop() const { return mReshapeFlags & FOLLOWS_TOP; }
- bool followsBottom() const { return mReshapeFlags & FOLLOWS_BOTTOM; }
- bool followsAll() const { return mReshapeFlags & FOLLOWS_ALL; }
-
- const LLRect& getRect() const { return mRect; }
- const LLRect& getBoundingRect() const { return mBoundingRect; }
- LLRect getLocalBoundingRect() const;
- LLRect calcScreenRect() const;
- LLRect calcScreenBoundingRect() const;
- LLRect getLocalRect() const;
- virtual LLRect getSnapRect() const;
- LLRect getLocalSnapRect() const;
-
- std::string getLayout() { return mLayout; }
-
- // Override and return required size for this object. 0 for width/height means don't care.
- virtual LLRect getRequiredRect();
- LLRect calcBoundingRect();
- void updateBoundingRect();
-
- LLView* getRootView();
- LLView* getParent() const { return mParentView; }
- LLView* getFirstChild() const { return (mChildList.empty()) ? NULL : *(mChildList.begin()); }
- LLView* findPrevSibling(LLView* child);
- LLView* findNextSibling(LLView* child);
- S32 getChildCount() const { return (S32)mChildList.size(); }
- template<class _Pr3> void sortChildren(_Pr3 _Pred) { mChildList.sort(_Pred); }
- bool hasAncestor(const LLView* parentp) const;
- bool hasChild(const std::string& childname, bool recurse = false) const;
- bool childHasKeyboardFocus( const std::string& childname ) const;
-
- // these iterators are used for collapsing various tree traversals into for loops
- typedef LLTreeDFSIter<LLView, child_list_const_iter_t> tree_iterator_t;
- tree_iterator_t beginTreeDFS();
- tree_iterator_t endTreeDFS();
-
- typedef LLTreeDFSPostIter<LLView, child_list_const_iter_t> tree_post_iterator_t;
- tree_post_iterator_t beginTreeDFSPost();
- tree_post_iterator_t endTreeDFSPost();
-
- typedef LLTreeBFSIter<LLView, child_list_const_iter_t> bfs_tree_iterator_t;
- bfs_tree_iterator_t beginTreeBFS();
- bfs_tree_iterator_t endTreeBFS();
-
-
- typedef LLTreeDownIter<LLView> root_to_view_iterator_t;
- root_to_view_iterator_t beginRootToView();
- root_to_view_iterator_t endRootToView();
-
- //
- // UTILITIES
- //
-
- // Default behavior is to use reshape flags to resize child views
- virtual void reshape(S32 width, S32 height, bool called_from_parent = true);
- virtual void translate( S32 x, S32 y );
- void setOrigin( S32 x, S32 y ) { mRect.translate( x - mRect.mLeft, y - mRect.mBottom ); }
- bool translateIntoRect( const LLRect& constraint, S32 min_overlap_pixels = S32_MAX);
- bool translateRectIntoRect( const LLRect& rect, const LLRect& constraint, S32 min_overlap_pixels = S32_MAX);
- bool translateIntoRectWithExclusion( const LLRect& inside, const LLRect& exclude, S32 min_overlap_pixels = S32_MAX);
- void centerWithin(const LLRect& bounds);
-
- void setShape(const LLRect& new_rect, bool by_user = false);
- virtual LLView* findSnapRect(LLRect& new_rect, const LLCoordGL& mouse_dir, LLView::ESnapType snap_type, S32 threshold, S32 padding = 0);
- virtual LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding = 0);
- virtual bool canSnapTo(const LLView* other_view);
- virtual void setSnappedTo(const LLView* snap_view);
-
- // inherited from LLFocusableElement
- /* virtual */ bool handleKey(KEY key, MASK mask, bool called_from_parent);
- /* virtual */ bool handleKeyUp(KEY key, MASK mask, bool called_from_parent);
- /* virtual */ bool handleUnicodeChar(llwchar uni_char, bool called_from_parent);
-
- virtual bool handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg);
-
- virtual void draw();
-
- void parseFollowsFlags(const LLView::Params& params);
-
- // Some widgets, like close box buttons, don't need to be saved
- bool getFromXUI() const { return mFromXUI; }
- void setFromXUI(bool b) { mFromXUI = b; }
-
- typedef enum e_hit_test_type
- {
- HIT_TEST_USE_BOUNDING_RECT,
- HIT_TEST_IGNORE_BOUNDING_RECT
- }EHitTestType;
-
- bool parentPointInView(S32 x, S32 y, EHitTestType type = HIT_TEST_USE_BOUNDING_RECT) const;
- bool pointInView(S32 x, S32 y, EHitTestType type = HIT_TEST_USE_BOUNDING_RECT) const;
- bool blockMouseEvent(S32 x, S32 y) const;
-
- // See LLMouseHandler virtuals for screenPointToLocal and localPointToScreen
- bool localPointToOtherView( S32 x, S32 y, S32 *other_x, S32 *other_y, const LLView* other_view) const;
- bool localRectToOtherView( const LLRect& local, LLRect* other, const LLView* other_view ) const;
- void screenRectToLocal( const LLRect& screen, LLRect* local ) const;
- void localRectToScreen( const LLRect& local, LLRect* screen ) const;
-
- LLControlVariable *findControl(const std::string& name);
-
- const child_list_t* getChildList() const { return &mChildList; }
- child_list_const_iter_t beginChild() const { return mChildList.begin(); }
- child_list_const_iter_t endChild() const { return mChildList.end(); }
-
- // LLMouseHandler functions
- // Default behavior is to pass events to children
- /*virtual*/ bool handleHover(S32 x, S32 y, MASK mask);
- /*virtual*/ bool handleMouseUp(S32 x, S32 y, MASK mask);
- /*virtual*/ bool handleMouseDown(S32 x, S32 y, MASK mask);
- /*virtual*/ bool handleMiddleMouseUp(S32 x, S32 y, MASK mask);
- /*virtual*/ bool handleMiddleMouseDown(S32 x, S32 y, MASK mask);
- /*virtual*/ bool handleDoubleClick(S32 x, S32 y, MASK mask);
- /*virtual*/ bool handleScrollWheel(S32 x, S32 y, S32 clicks);
- /*virtual*/ bool handleScrollHWheel(S32 x, S32 y, S32 clicks);
- /*virtual*/ bool handleRightMouseDown(S32 x, S32 y, MASK mask);
- /*virtual*/ bool handleRightMouseUp(S32 x, S32 y, MASK mask);
- /*virtual*/ bool handleToolTip(S32 x, S32 y, MASK mask);
-
- /*virtual*/ const std::string& getName() const;
- /*virtual*/ void onMouseCaptureLost();
- /*virtual*/ bool hasMouseCapture();
- /*virtual*/ void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const;
- /*virtual*/ void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const;
-
- virtual LLView* childFromPoint(S32 x, S32 y, bool recur=false);
-
- // view-specific handlers
- virtual void onMouseEnter(S32 x, S32 y, MASK mask);
- virtual void onMouseLeave(S32 x, S32 y, MASK mask);
-
- std::string getPathname() const;
- // static method handles NULL pointer too
- static std::string getPathname(const LLView*);
-
- template <class T> T* findChild(const std::string& name, bool recurse = true) const
- {
- LLView* child = findChildView(name, recurse);
- T* result = dynamic_cast<T*>(child);
- return result;
- }
-
- template <class T> T* getChild(const std::string& name, bool recurse = true) const;
-
- template <class T> T& getChildRef(const std::string& name, bool recurse = true) const
- {
- return *getChild<T>(name, recurse);
- }
-
- virtual LLView* getChildView(const std::string& name, bool recurse = true) const;
- virtual LLView* findChildView(const std::string& name, bool recurse = true) const;
-
- template <class T> T* getDefaultWidget(const std::string& name) const
- {
- LLView* widgetp = getDefaultWidgetContainer().findChildView(name);
- return dynamic_cast<T*>(widgetp);
- }
-
- template <class T> T* getParentByType() const
- {
- LLView* parent = getParent();
- while(parent)
- {
- if (dynamic_cast<T*>(parent))
- {
- return static_cast<T*>(parent);
- }
- parent = parent->getParent();
- }
- return NULL;
- }
-
- //////////////////////////////////////////////
- // statics
- //////////////////////////////////////////////
- //static LLFontGL::HAlign selectFontHAlign(LLXMLNodePtr node);
-
- // focuses the item in the list after the currently-focused item, wrapping if necessary
- static bool focusNext(LLView::child_list_t & result);
- // focuses the item in the list before the currently-focused item, wrapping if necessary
- static bool focusPrev(LLView::child_list_t & result);
-
- // returns query for iterating over controls in tab order
- static const LLViewQuery & getTabOrderQuery();
- // return query for iterating over focus roots in tab order
- static const LLViewQuery & getFocusRootsQuery();
-
- static LLWindow* getWindow(void) { return LLUI::getInstance()->mWindow; }
-
- // Set up params after XML load before calling new(),
- // usually to adjust layout.
- static void applyXUILayout(Params& p, LLView* parent, LLRect layout_rect = LLRect());
-
- // For re-export of floaters and panels, convert the coordinate system
- // to be top-left based.
- static void setupParamsForExport(Params& p, LLView* parent);
-
- //virtual bool addChildFromParam(const LLInitParam::BaseBlock& params) { return true; }
- virtual bool handleKeyHere(KEY key, MASK mask);
- virtual bool handleKeyUpHere(KEY key, MASK mask);
- virtual bool handleUnicodeCharHere(llwchar uni_char);
-
- virtual void handleReshape(const LLRect& rect, bool by_user);
- virtual void dirtyRect();
-
- //send custom notification to LLView parent
- virtual S32 notifyParent(const LLSD& info);
-
- //send custom notification to all view childrend
- // return true if _any_ children return true. otherwise false.
- virtual bool notifyChildren(const LLSD& info);
-
- //send custom notification to current view
- virtual S32 notify(const LLSD& info) { return 0;};
-
- static const LLViewDrawContext& getDrawContext();
-
- // Returns useful information about this ui widget.
- LLSD getInfo(void);
-
-protected:
- void drawDebugRect();
- void drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, bool force_draw = false);
- void drawChildren();
- bool visibleAndContains(S32 local_x, S32 local_Y);
- bool visibleEnabledAndContains(S32 local_x, S32 local_y);
- void logMouseEvent();
-
- LLView* childrenHandleKey(KEY key, MASK mask);
- LLView* childrenHandleKeyUp(KEY key, MASK mask);
- LLView* childrenHandleUnicodeChar(llwchar uni_char);
- LLView* childrenHandleDragAndDrop(S32 x, S32 y, MASK mask,
- bool drop,
- EDragAndDropType type,
- void* data,
- EAcceptance* accept,
- std::string& tooltip_msg);
-
- LLView* childrenHandleHover(S32 x, S32 y, MASK mask);
- LLView* childrenHandleMouseUp(S32 x, S32 y, MASK mask);
- LLView* childrenHandleMouseDown(S32 x, S32 y, MASK mask);
- LLView* childrenHandleMiddleMouseUp(S32 x, S32 y, MASK mask);
- LLView* childrenHandleMiddleMouseDown(S32 x, S32 y, MASK mask);
- LLView* childrenHandleDoubleClick(S32 x, S32 y, MASK mask);
- LLView* childrenHandleScrollWheel(S32 x, S32 y, S32 clicks);
- LLView* childrenHandleScrollHWheel(S32 x, S32 y, S32 clicks);
- LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask);
- LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask);
- LLView* childrenHandleToolTip(S32 x, S32 y, MASK mask);
-
- ECursorType mHoverCursor;
-
- virtual void addInfo(LLSD & info);
-private:
-
- template <typename METHOD, typename XDATA>
- LLView* childrenHandleMouseEvent(const METHOD& method, S32 x, S32 y, XDATA extra, bool allow_mouse_block = true);
-
- template <typename METHOD, typename CHARTYPE>
- LLView* childrenHandleCharEvent(const std::string& desc, const METHOD& method,
- CHARTYPE c, MASK mask);
-
- // adapter to blur distinction between handleKey() and handleUnicodeChar()
- // for childrenHandleCharEvent()
- bool handleUnicodeCharWithDummyMask(llwchar uni_char, MASK /* dummy */, bool from_parent)
- {
- return handleUnicodeChar(uni_char, from_parent);
- }
-
- LLView* mParentView;
- child_list_t mChildList;
-
- // location in pixels, relative to surrounding structure, bottom,left=0,0
- bool mVisible;
- LLRect mRect;
- LLRect mBoundingRect;
-
- std::string mLayout;
- std::string mName;
-
- U32 mReshapeFlags;
-
- child_tab_order_t mTabOrder;
- S32 mDefaultTabGroup;
- S32 mLastTabGroup;
-
- bool mEnabled; // Enabled means "accepts input that has an effect on the state of the application."
- // A disabled view, for example, may still have a scrollbar that responds to mouse events.
- bool mMouseOpaque; // Opaque views handle all mouse events that are over their rect.
- LLUIString mToolTipMsg; // isNull() is true if none.
-
- U8 mSoundFlags;
- bool mFromXUI;
-
- bool mIsFocusRoot;
- bool mUseBoundingRect; // hit test against bounding rectangle that includes all child elements
-
- bool mLastVisible;
-
- bool mInDraw;
-
- static LLWindow* sWindow; // All root views must know about their window.
-
- typedef std::map<std::string, LLView*> default_widget_map_t;
- // allocate this map no demand, as it is rarely needed
- mutable LLView* mDefaultWidgets;
-
- LLView& getDefaultWidgetContainer() const;
-
- // This allows special mouse-event targeting logic for testing.
- typedef boost::function<bool(const LLView*, S32 x, S32 y)> DrilldownFunc;
- static DrilldownFunc sDrilldown;
-
-public:
- // This is the only public accessor to alter sDrilldown. This is not
- // an accident. The intended usage pattern is like:
- // {
- // LLView::TemporaryDrilldownFunc scoped_func(myfunctor);
- // // ... test with myfunctor ...
- // } // exiting block restores original LLView::sDrilldown
- class TemporaryDrilldownFunc: public boost::noncopyable
- {
- public:
- TemporaryDrilldownFunc(const DrilldownFunc& func):
- mOldDrilldown(sDrilldown)
- {
- sDrilldown = func;
- }
-
- ~TemporaryDrilldownFunc()
- {
- sDrilldown = mOldDrilldown;
- }
-
- private:
- DrilldownFunc mOldDrilldown;
- };
-
- // Depth in view hierarchy during rendering
- static S32 sDepth;
-
- // Draw debug rectangles around widgets to help with alignment and spacing
- static bool sDebugRects;
-
- // Show hexadecimal byte values of unicode symbols in a tooltip
- static bool sDebugUnicode;
-
- // Show camera position and direction in Camera Controls floater
- static bool sDebugCamera;
-
- static bool sIsRectDirty;
- static LLRect sDirtyRect;
-
- // Draw widget names and sizes when drawing debug rectangles, turning this
- // off is useful to make the rectangles themselves easier to see.
- static bool sDebugRectsShowNames;
-
- static bool sDebugKeys;
- static bool sDebugMouseHandling;
- static std::string sMouseHandlerMessage;
- static S32 sSelectID;
- static std::set<LLView*> sPreviewHighlightedElements; // DEV-16869
- static bool sHighlightingDiffs; // DEV-16869
- static LLView* sPreviewClickedElement; // DEV-16869
- static bool sDrawPreviewHighlights;
- static S32 sLastLeftXML;
- static S32 sLastBottomXML;
- static bool sForceReshape;
-};
-
-namespace LLInitParam
-{
-template<>
-struct TypeValues<LLView::EOrientation> : public LLInitParam::TypeValuesHelper<LLView::EOrientation>
-{
- static void declareValues();
-};
-}
-
-template <class T> T* LLView::getChild(const std::string& name, bool recurse) const
-{
- LLView* child = findChildView(name, recurse);
- T* result = dynamic_cast<T*>(child);
- if (!result)
- {
- // did we find *something* with that name?
- if (child)
- {
- LL_WARNS() << "Found child named \"" << name << "\" but of wrong type " << typeid(*child).name() << ", expecting " << typeid(T*).name() << LL_ENDL;
- }
- result = getDefaultWidget<T>(name);
- if (!result)
- {
- result = LLUICtrlFactory::getDefaultWidget<T>(name);
- if (!result)
- {
- LL_ERRS() << "Failed to create dummy " << typeid(T).name() << LL_ENDL;
- }
-
- // *NOTE: You cannot call mFoo = getChild<LLFoo>("bar")
- // in a floater or panel constructor. The widgets will not
- // be ready. Instead, put it in postBuild().
- LL_WARNS() << "Making dummy " << typeid(T).name() << " named \"" << name << "\" in " << getName() << LL_ENDL;
-
- getDefaultWidgetContainer().addChild(result);
- }
- }
- return result;
-}
-
-// Compiler optimization - don't generate these specializations inline,
-// require explicit specialization. See llbutton.cpp for an example.
-#ifndef LLVIEW_CPP
-extern template class LLView* LLView::getChild<class LLView>(
- const std::string& name, bool recurse) const;
-#endif
-
-#endif //LL_LLVIEW_H
+/** + * @file llview.h + * @brief Container for other views, anything that draws. + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLVIEW_H +#define LL_LLVIEW_H + +// A view is an area in a window that can draw. It might represent +// the HUD or a dialog box or a button. It can also contain sub-views +// and child widgets + +#include "stdtypes.h" +#include "llcoord.h" +#include "llfontgl.h" +#include "llhandle.h" +#include "llmortician.h" +#include "llmousehandler.h" +#include "llstring.h" +#include "llrect.h" +#include "llui.h" +#include "lluistring.h" +#include "llviewquery.h" +#include "lluistring.h" +#include "llcursortypes.h" +#include "lluictrlfactory.h" +#include "lltreeiterators.h" +#include "llfocusmgr.h" + +#include <list> +#include <boost/function.hpp> +#include <boost/noncopyable.hpp> + +class LLSD; + +const U32 FOLLOWS_NONE = 0x00; +const U32 FOLLOWS_LEFT = 0x01; +const U32 FOLLOWS_RIGHT = 0x02; +const U32 FOLLOWS_TOP = 0x10; +const U32 FOLLOWS_BOTTOM = 0x20; +const U32 FOLLOWS_ALL = 0x33; + +const bool MOUSE_OPAQUE = true; +const bool NOT_MOUSE_OPAQUE = false; + +const U32 GL_NAME_UI_RESERVED = 2; + + +// maintains render state during traversal of UI tree +class LLViewDrawContext +{ +public: + F32 mAlpha; + + LLViewDrawContext(F32 alpha = 1.f) + : mAlpha(alpha) + { + if (!sDrawContextStack.empty()) + { + LLViewDrawContext* context_top = sDrawContextStack.back(); + // merge with top of stack + mAlpha *= context_top->mAlpha; + } + sDrawContextStack.push_back(this); + } + + ~LLViewDrawContext() + { + sDrawContextStack.pop_back(); + } + + static const LLViewDrawContext& getCurrentContext(); + +private: + static std::vector<LLViewDrawContext*> sDrawContextStack; +}; + +class LLView +: public LLMouseHandler, // handles mouse events + public LLFocusableElement, // handles keyboard events + public LLMortician, // lazy deletion + public LLHandleProvider<LLView> // passes out weak references to self +{ +public: + + enum EOrientation { HORIZONTAL, VERTICAL, ORIENTATION_COUNT }; + + struct Follows : public LLInitParam::ChoiceBlock<Follows> + { + Alternative<std::string> string; + Alternative<U32> flags; + + Follows(); + }; + + struct Params : public LLInitParam::Block<Params> + { + Mandatory<std::string> name; + + Optional<bool> enabled, + visible, + mouse_opaque, + use_bounding_rect, + from_xui, + focus_root; + + Optional<S32> tab_group, + default_tab_group; + Optional<std::string> tool_tip; + + Optional<S32> sound_flags; + Optional<Follows> follows; + Optional<std::string> hover_cursor; + + Optional<std::string> layout; + Optional<LLRect> rect; + + // Historical bottom-left layout used bottom_delta and left_delta + // for relative positioning. New layout "topleft" prefers specifying + // based on top edge. + Optional<S32> bottom_delta, // from last bottom to my bottom + top_pad, // from last bottom to my top + top_delta, // from last top to my top + left_pad, // from last right to my left + left_delta; // from last left to my left + + //FIXME: get parent context involved in parsing traversal + Ignored needs_translate, // cue for translation tools + xmlns, // xml namespace + xmlns_xsi, // xml namespace + xsi_schemaLocation, // xml schema + xsi_type; // xml schema type + + Params(); + }; + + // most widgets are valid children of LLView + typedef LLDefaultChildRegistry child_registry_t; + + void initFromParams(const LLView::Params&); + +protected: + LLView(const LLView::Params&); + friend class LLUICtrlFactory; + +private: + // widgets in general are not copyable + LLView(const LLView& other); +public: +//#if LL_DEBUG + static bool sIsDrawing; +//#endif + enum ESoundFlags + { + SILENT = 0, + MOUSE_DOWN = 1, + MOUSE_UP = 2 + }; + + enum ESnapType + { + SNAP_PARENT, + SNAP_SIBLINGS, + SNAP_PARENT_AND_SIBLINGS + }; + + enum ESnapEdge + { + SNAP_LEFT, + SNAP_TOP, + SNAP_RIGHT, + SNAP_BOTTOM + }; + + typedef std::list<LLView*> child_list_t; + typedef child_list_t::iterator child_list_iter_t; + typedef child_list_t::const_iterator child_list_const_iter_t; + typedef child_list_t::reverse_iterator child_list_reverse_iter_t; + typedef child_list_t::const_reverse_iterator child_list_const_reverse_iter_t; + + typedef std::pair<LLView *, S32> tab_order_pair_t; + // this structure primarily sorts by the tab group, secondarily by the insertion ordinal (lastly by the value of the pointer) + typedef std::map<const LLView*, S32> child_tab_order_t; + typedef child_tab_order_t::iterator child_tab_order_iter_t; + typedef child_tab_order_t::const_iterator child_tab_order_const_iter_t; + typedef child_tab_order_t::reverse_iterator child_tab_order_reverse_iter_t; + typedef child_tab_order_t::const_reverse_iterator child_tab_order_const_reverse_iter_t; + + virtual ~LLView(); + + // Some UI widgets need to be added as controls. Others need to + // be added as regular view children. isCtrl should return true + // if a widget needs to be added as a ctrl + virtual bool isCtrl() const; + + virtual bool isPanel() const; + + // + // MANIPULATORS + // + void setMouseOpaque( bool b ) { mMouseOpaque = b; } + bool getMouseOpaque() const { return mMouseOpaque; } + void setToolTip( const LLStringExplicit& msg ); + bool setToolTipArg( const LLStringExplicit& key, const LLStringExplicit& text ); + void setToolTipArgs( const LLStringUtil::format_map_t& args ); + + virtual void setRect(const LLRect &rect); + void setFollows(U32 flags) { mReshapeFlags = flags; } + + // deprecated, use setFollows() with FOLLOWS_LEFT | FOLLOWS_TOP, etc. + void setFollowsNone() { mReshapeFlags = FOLLOWS_NONE; } + void setFollowsLeft() { mReshapeFlags |= FOLLOWS_LEFT; } + void setFollowsTop() { mReshapeFlags |= FOLLOWS_TOP; } + void setFollowsRight() { mReshapeFlags |= FOLLOWS_RIGHT; } + void setFollowsBottom() { mReshapeFlags |= FOLLOWS_BOTTOM; } + void setFollowsAll() { mReshapeFlags |= FOLLOWS_ALL; } + + void setSoundFlags(U8 flags) { mSoundFlags = flags; } + void setName(std::string name) { mName = name; } + void setUseBoundingRect( bool use_bounding_rect ); + bool getUseBoundingRect() const; + + ECursorType getHoverCursor() { return mHoverCursor; } + + static F32 getTooltipTimeout(); + virtual const std::string getToolTip() const; + virtual const std::string& getText() const { return LLStringUtil::null; } + virtual const LLFontGL* getFont() const { return nullptr; } + + void sendChildToFront(LLView* child); + void sendChildToBack(LLView* child); + + virtual bool addChild(LLView* view, S32 tab_group = 0); + + // implemented in terms of addChild() + bool addChildInBack(LLView* view, S32 tab_group = 0); + + // remove the specified child from the view, and set it's parent to NULL. + virtual void removeChild(LLView* view); + + virtual bool postBuild() { return true; } + + const child_tab_order_t& getTabOrder() const { return mTabOrder; } + + void setDefaultTabGroup(S32 d) { mDefaultTabGroup = d; } + S32 getDefaultTabGroup() const { return mDefaultTabGroup; } + S32 getLastTabGroup() { return mLastTabGroup; } + + bool isInVisibleChain() const; + bool isInEnabledChain() const; + + void setFocusRoot(bool b) { mIsFocusRoot = b; } + bool isFocusRoot() const { return mIsFocusRoot; } + virtual bool canFocusChildren() const; + + bool focusNextRoot(); + bool focusPrevRoot(); + + // Normally we want the app menus to get priority on accelerated keys + // However, sometimes we want to give specific views a first chance + // iat handling them. (eg. the script editor) + virtual bool hasAccelerators() const { return false; }; + + // delete all children. Override this function if you need to + // perform any extra clean up such as cached pointers to selected + // children, etc. + virtual void deleteAllChildren(); + + void setAllChildrenEnabled(bool b); + + virtual void setVisible(bool visible); + void setVisibleDirect(bool visible) { mVisible = visible; } + const bool& getVisible() const { return mVisible; } + virtual void setEnabled(bool enabled); + bool getEnabled() const { return mEnabled; } + /// 'available' in this context means 'visible and enabled': in other + /// words, can a user actually interact with this? + virtual bool isAvailable() const; + /// The static isAvailable() tests an LLView* that could be NULL. + static bool isAvailable(const LLView* view); + U8 getSoundFlags() const { return mSoundFlags; } + + virtual bool setLabelArg( const std::string& key, const LLStringExplicit& text ); + + virtual void onVisibilityChange ( bool new_visibility ); + virtual void onUpdateScrollToChild(const LLUICtrl * cntrl); + + void pushVisible(bool visible) { mLastVisible = mVisible; setVisible(visible); } + void popVisible() { setVisible(mLastVisible); } + bool getLastVisible() const { return mLastVisible; } + + U32 getFollows() const { return mReshapeFlags; } + bool followsLeft() const { return mReshapeFlags & FOLLOWS_LEFT; } + bool followsRight() const { return mReshapeFlags & FOLLOWS_RIGHT; } + bool followsTop() const { return mReshapeFlags & FOLLOWS_TOP; } + bool followsBottom() const { return mReshapeFlags & FOLLOWS_BOTTOM; } + bool followsAll() const { return mReshapeFlags & FOLLOWS_ALL; } + + const LLRect& getRect() const { return mRect; } + const LLRect& getBoundingRect() const { return mBoundingRect; } + LLRect getLocalBoundingRect() const; + LLRect calcScreenRect() const; + LLRect calcScreenBoundingRect() const; + LLRect getLocalRect() const; + virtual LLRect getSnapRect() const; + LLRect getLocalSnapRect() const; + + std::string getLayout() { return mLayout; } + + // Override and return required size for this object. 0 for width/height means don't care. + virtual LLRect getRequiredRect(); + LLRect calcBoundingRect(); + void updateBoundingRect(); + + LLView* getRootView(); + LLView* getParent() const { return mParentView; } + LLView* getFirstChild() const { return (mChildList.empty()) ? NULL : *(mChildList.begin()); } + LLView* findPrevSibling(LLView* child); + LLView* findNextSibling(LLView* child); + S32 getChildCount() const { return (S32)mChildList.size(); } + template<class _Pr3> void sortChildren(_Pr3 _Pred) { mChildList.sort(_Pred); } + bool hasAncestor(const LLView* parentp) const; + bool hasChild(const std::string& childname, bool recurse = false) const; + bool childHasKeyboardFocus( const std::string& childname ) const; + + // these iterators are used for collapsing various tree traversals into for loops + typedef LLTreeDFSIter<LLView, child_list_const_iter_t> tree_iterator_t; + tree_iterator_t beginTreeDFS(); + tree_iterator_t endTreeDFS(); + + typedef LLTreeDFSPostIter<LLView, child_list_const_iter_t> tree_post_iterator_t; + tree_post_iterator_t beginTreeDFSPost(); + tree_post_iterator_t endTreeDFSPost(); + + typedef LLTreeBFSIter<LLView, child_list_const_iter_t> bfs_tree_iterator_t; + bfs_tree_iterator_t beginTreeBFS(); + bfs_tree_iterator_t endTreeBFS(); + + + typedef LLTreeDownIter<LLView> root_to_view_iterator_t; + root_to_view_iterator_t beginRootToView(); + root_to_view_iterator_t endRootToView(); + + // + // UTILITIES + // + + // Default behavior is to use reshape flags to resize child views + virtual void reshape(S32 width, S32 height, bool called_from_parent = true); + virtual void translate( S32 x, S32 y ); + void setOrigin( S32 x, S32 y ) { mRect.translate( x - mRect.mLeft, y - mRect.mBottom ); } + bool translateIntoRect( const LLRect& constraint, S32 min_overlap_pixels = S32_MAX); + bool translateRectIntoRect( const LLRect& rect, const LLRect& constraint, S32 min_overlap_pixels = S32_MAX); + bool translateIntoRectWithExclusion( const LLRect& inside, const LLRect& exclude, S32 min_overlap_pixels = S32_MAX); + void centerWithin(const LLRect& bounds); + + void setShape(const LLRect& new_rect, bool by_user = false); + virtual LLView* findSnapRect(LLRect& new_rect, const LLCoordGL& mouse_dir, LLView::ESnapType snap_type, S32 threshold, S32 padding = 0); + virtual LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding = 0); + virtual bool canSnapTo(const LLView* other_view); + virtual void setSnappedTo(const LLView* snap_view); + + // inherited from LLFocusableElement + /* virtual */ bool handleKey(KEY key, MASK mask, bool called_from_parent); + /* virtual */ bool handleKeyUp(KEY key, MASK mask, bool called_from_parent); + /* virtual */ bool handleUnicodeChar(llwchar uni_char, bool called_from_parent); + + virtual bool handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg); + + virtual void draw(); + + void parseFollowsFlags(const LLView::Params& params); + + // Some widgets, like close box buttons, don't need to be saved + bool getFromXUI() const { return mFromXUI; } + void setFromXUI(bool b) { mFromXUI = b; } + + typedef enum e_hit_test_type + { + HIT_TEST_USE_BOUNDING_RECT, + HIT_TEST_IGNORE_BOUNDING_RECT + }EHitTestType; + + bool parentPointInView(S32 x, S32 y, EHitTestType type = HIT_TEST_USE_BOUNDING_RECT) const; + bool pointInView(S32 x, S32 y, EHitTestType type = HIT_TEST_USE_BOUNDING_RECT) const; + bool blockMouseEvent(S32 x, S32 y) const; + + // See LLMouseHandler virtuals for screenPointToLocal and localPointToScreen + bool localPointToOtherView( S32 x, S32 y, S32 *other_x, S32 *other_y, const LLView* other_view) const; + bool localRectToOtherView( const LLRect& local, LLRect* other, const LLView* other_view ) const; + void screenRectToLocal( const LLRect& screen, LLRect* local ) const; + void localRectToScreen( const LLRect& local, LLRect* screen ) const; + + LLControlVariable *findControl(const std::string& name); + + const child_list_t* getChildList() const { return &mChildList; } + child_list_const_iter_t beginChild() const { return mChildList.begin(); } + child_list_const_iter_t endChild() const { return mChildList.end(); } + + // LLMouseHandler functions + // Default behavior is to pass events to children + /*virtual*/ bool handleHover(S32 x, S32 y, MASK mask); + /*virtual*/ bool handleMouseUp(S32 x, S32 y, MASK mask); + /*virtual*/ bool handleMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ bool handleMiddleMouseUp(S32 x, S32 y, MASK mask); + /*virtual*/ bool handleMiddleMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ bool handleDoubleClick(S32 x, S32 y, MASK mask); + /*virtual*/ bool handleScrollWheel(S32 x, S32 y, S32 clicks); + /*virtual*/ bool handleScrollHWheel(S32 x, S32 y, S32 clicks); + /*virtual*/ bool handleRightMouseDown(S32 x, S32 y, MASK mask); + /*virtual*/ bool handleRightMouseUp(S32 x, S32 y, MASK mask); + /*virtual*/ bool handleToolTip(S32 x, S32 y, MASK mask); + + /*virtual*/ const std::string& getName() const; + /*virtual*/ void onMouseCaptureLost(); + /*virtual*/ bool hasMouseCapture(); + /*virtual*/ void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const; + /*virtual*/ void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const; + + virtual LLView* childFromPoint(S32 x, S32 y, bool recur=false); + + // view-specific handlers + virtual void onMouseEnter(S32 x, S32 y, MASK mask); + virtual void onMouseLeave(S32 x, S32 y, MASK mask); + + std::string getPathname() const; + // static method handles NULL pointer too + static std::string getPathname(const LLView*); + + template <class T> T* findChild(const std::string& name, bool recurse = true) const + { + LLView* child = findChildView(name, recurse); + T* result = dynamic_cast<T*>(child); + return result; + } + + template <class T> T* getChild(const std::string& name, bool recurse = true) const; + + template <class T> T& getChildRef(const std::string& name, bool recurse = true) const + { + return *getChild<T>(name, recurse); + } + + virtual LLView* getChildView(const std::string& name, bool recurse = true) const; + virtual LLView* findChildView(const std::string& name, bool recurse = true) const; + + template <class T> T* getDefaultWidget(const std::string& name) const + { + LLView* widgetp = getDefaultWidgetContainer().findChildView(name); + return dynamic_cast<T*>(widgetp); + } + + template <class T> T* getParentByType() const + { + LLView* parent = getParent(); + while(parent) + { + if (dynamic_cast<T*>(parent)) + { + return static_cast<T*>(parent); + } + parent = parent->getParent(); + } + return NULL; + } + + ////////////////////////////////////////////// + // statics + ////////////////////////////////////////////// + //static LLFontGL::HAlign selectFontHAlign(LLXMLNodePtr node); + + // focuses the item in the list after the currently-focused item, wrapping if necessary + static bool focusNext(LLView::child_list_t & result); + // focuses the item in the list before the currently-focused item, wrapping if necessary + static bool focusPrev(LLView::child_list_t & result); + + // returns query for iterating over controls in tab order + static const LLViewQuery & getTabOrderQuery(); + // return query for iterating over focus roots in tab order + static const LLViewQuery & getFocusRootsQuery(); + + static LLWindow* getWindow(void) { return LLUI::getInstance()->mWindow; } + + // Set up params after XML load before calling new(), + // usually to adjust layout. + static void applyXUILayout(Params& p, LLView* parent, LLRect layout_rect = LLRect()); + + // For re-export of floaters and panels, convert the coordinate system + // to be top-left based. + static void setupParamsForExport(Params& p, LLView* parent); + + //virtual bool addChildFromParam(const LLInitParam::BaseBlock& params) { return true; } + virtual bool handleKeyHere(KEY key, MASK mask); + virtual bool handleKeyUpHere(KEY key, MASK mask); + virtual bool handleUnicodeCharHere(llwchar uni_char); + + virtual void handleReshape(const LLRect& rect, bool by_user); + virtual void dirtyRect(); + + //send custom notification to LLView parent + virtual S32 notifyParent(const LLSD& info); + + //send custom notification to all view childrend + // return true if _any_ children return true. otherwise false. + virtual bool notifyChildren(const LLSD& info); + + //send custom notification to current view + virtual S32 notify(const LLSD& info) { return 0;}; + + static const LLViewDrawContext& getDrawContext(); + + // Returns useful information about this ui widget. + LLSD getInfo(void); + +protected: + void drawDebugRect(); + void drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, bool force_draw = false); + void drawChildren(); + bool visibleAndContains(S32 local_x, S32 local_Y); + bool visibleEnabledAndContains(S32 local_x, S32 local_y); + void logMouseEvent(); + + LLView* childrenHandleKey(KEY key, MASK mask); + LLView* childrenHandleKeyUp(KEY key, MASK mask); + LLView* childrenHandleUnicodeChar(llwchar uni_char); + LLView* childrenHandleDragAndDrop(S32 x, S32 y, MASK mask, + bool drop, + EDragAndDropType type, + void* data, + EAcceptance* accept, + std::string& tooltip_msg); + + LLView* childrenHandleHover(S32 x, S32 y, MASK mask); + LLView* childrenHandleMouseUp(S32 x, S32 y, MASK mask); + LLView* childrenHandleMouseDown(S32 x, S32 y, MASK mask); + LLView* childrenHandleMiddleMouseUp(S32 x, S32 y, MASK mask); + LLView* childrenHandleMiddleMouseDown(S32 x, S32 y, MASK mask); + LLView* childrenHandleDoubleClick(S32 x, S32 y, MASK mask); + LLView* childrenHandleScrollWheel(S32 x, S32 y, S32 clicks); + LLView* childrenHandleScrollHWheel(S32 x, S32 y, S32 clicks); + LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask); + LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask); + LLView* childrenHandleToolTip(S32 x, S32 y, MASK mask); + + ECursorType mHoverCursor; + + virtual void addInfo(LLSD & info); +private: + + template <typename METHOD, typename XDATA> + LLView* childrenHandleMouseEvent(const METHOD& method, S32 x, S32 y, XDATA extra, bool allow_mouse_block = true); + + template <typename METHOD, typename CHARTYPE> + LLView* childrenHandleCharEvent(const std::string& desc, const METHOD& method, + CHARTYPE c, MASK mask); + + // adapter to blur distinction between handleKey() and handleUnicodeChar() + // for childrenHandleCharEvent() + bool handleUnicodeCharWithDummyMask(llwchar uni_char, MASK /* dummy */, bool from_parent) + { + return handleUnicodeChar(uni_char, from_parent); + } + + LLView* mParentView; + child_list_t mChildList; + + // location in pixels, relative to surrounding structure, bottom,left=0,0 + bool mVisible; + LLRect mRect; + LLRect mBoundingRect; + + std::string mLayout; + std::string mName; + + U32 mReshapeFlags; + + child_tab_order_t mTabOrder; + S32 mDefaultTabGroup; + S32 mLastTabGroup; + + bool mEnabled; // Enabled means "accepts input that has an effect on the state of the application." + // A disabled view, for example, may still have a scrollbar that responds to mouse events. + bool mMouseOpaque; // Opaque views handle all mouse events that are over their rect. + LLUIString mToolTipMsg; // isNull() is true if none. + + U8 mSoundFlags; + bool mFromXUI; + + bool mIsFocusRoot; + bool mUseBoundingRect; // hit test against bounding rectangle that includes all child elements + + bool mLastVisible; + + bool mInDraw; + + static LLWindow* sWindow; // All root views must know about their window. + + typedef std::map<std::string, LLView*> default_widget_map_t; + // allocate this map no demand, as it is rarely needed + mutable LLView* mDefaultWidgets; + + LLView& getDefaultWidgetContainer() const; + + // This allows special mouse-event targeting logic for testing. + typedef boost::function<bool(const LLView*, S32 x, S32 y)> DrilldownFunc; + static DrilldownFunc sDrilldown; + +public: + // This is the only public accessor to alter sDrilldown. This is not + // an accident. The intended usage pattern is like: + // { + // LLView::TemporaryDrilldownFunc scoped_func(myfunctor); + // // ... test with myfunctor ... + // } // exiting block restores original LLView::sDrilldown + class TemporaryDrilldownFunc: public boost::noncopyable + { + public: + TemporaryDrilldownFunc(const DrilldownFunc& func): + mOldDrilldown(sDrilldown) + { + sDrilldown = func; + } + + ~TemporaryDrilldownFunc() + { + sDrilldown = mOldDrilldown; + } + + private: + DrilldownFunc mOldDrilldown; + }; + + // Depth in view hierarchy during rendering + static S32 sDepth; + + // Draw debug rectangles around widgets to help with alignment and spacing + static bool sDebugRects; + + // Show hexadecimal byte values of unicode symbols in a tooltip + static bool sDebugUnicode; + + // Show camera position and direction in Camera Controls floater + static bool sDebugCamera; + + static bool sIsRectDirty; + static LLRect sDirtyRect; + + // Draw widget names and sizes when drawing debug rectangles, turning this + // off is useful to make the rectangles themselves easier to see. + static bool sDebugRectsShowNames; + + static bool sDebugKeys; + static bool sDebugMouseHandling; + static std::string sMouseHandlerMessage; + static S32 sSelectID; + static std::set<LLView*> sPreviewHighlightedElements; // DEV-16869 + static bool sHighlightingDiffs; // DEV-16869 + static LLView* sPreviewClickedElement; // DEV-16869 + static bool sDrawPreviewHighlights; + static S32 sLastLeftXML; + static S32 sLastBottomXML; + static bool sForceReshape; +}; + +namespace LLInitParam +{ +template<> +struct TypeValues<LLView::EOrientation> : public LLInitParam::TypeValuesHelper<LLView::EOrientation> +{ + static void declareValues(); +}; +} + +template <class T> T* LLView::getChild(const std::string& name, bool recurse) const +{ + LLView* child = findChildView(name, recurse); + T* result = dynamic_cast<T*>(child); + if (!result) + { + // did we find *something* with that name? + if (child) + { + LL_WARNS() << "Found child named \"" << name << "\" but of wrong type " << typeid(*child).name() << ", expecting " << typeid(T*).name() << LL_ENDL; + } + result = getDefaultWidget<T>(name); + if (!result) + { + result = LLUICtrlFactory::getDefaultWidget<T>(name); + if (!result) + { + LL_ERRS() << "Failed to create dummy " << typeid(T).name() << LL_ENDL; + } + + // *NOTE: You cannot call mFoo = getChild<LLFoo>("bar") + // in a floater or panel constructor. The widgets will not + // be ready. Instead, put it in postBuild(). + LL_WARNS() << "Making dummy " << typeid(T).name() << " named \"" << name << "\" in " << getName() << LL_ENDL; + + getDefaultWidgetContainer().addChild(result); + } + } + return result; +} + +// Compiler optimization - don't generate these specializations inline, +// require explicit specialization. See llbutton.cpp for an example. +#ifndef LLVIEW_CPP +extern template class LLView* LLView::getChild<class LLView>( + const std::string& name, bool recurse) const; +#endif + +#endif //LL_LLVIEW_H |