phoenix-firestorm/indra/llui/llview.h

493 lines
16 KiB
C++

/**
* @file llview.h
* @brief Container for other views, anything that draws.
*
* Copyright (c) 2001-$CurrentYear$, Linden Research, Inc.
* $License$
*/
#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 <iosfwd>
#include <list>
#include "lluixmltags.h"
#include "llrect.h"
#include "llmousehandler.h"
#include "stdenums.h"
#include "llsd.h"
#include "llstring.h"
#include "llnametable.h"
#include "llcoord.h"
#include "llmortician.h"
#include "llxmlnode.h"
#include "llfontgl.h"
#include "llviewquery.h"
#include "llui.h"
class LLColor4;
class LLWindow;
class LLUICtrl;
class LLScrollListItem;
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;
class LLSimpleListener;
class LLEventDispatcher;
class LLViewHandle
{
public:
LLViewHandle() { mID = 0; }
void init() { mID = ++sNextID; }
void markDead() { mID = 0; }
BOOL isDead() { return (mID == 0); }
friend bool operator==(const LLViewHandle& lhs, const LLViewHandle& rhs);
friend bool operator!=(const LLViewHandle& lhs, const LLViewHandle& rhs);
friend bool operator<(const LLViewHandle &a, const LLViewHandle &b);
public:
static LLViewHandle sDeadHandle;
protected:
S32 mID;
static S32 sNextID;
};
class LLView : public LLMouseHandler, public LLMortician, public LLSimpleListenerObservable
{
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::vector<LLUICtrl *> ctrl_list_t;
typedef std::pair<S32, S32> tab_order_t;
typedef std::pair<LLUICtrl *, tab_order_t> 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 LLUICtrl*, tab_order_t> 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;
private:
LLView* mParentView;
child_list_t mChildList;
protected:
LLString mName;
// location in pixels, relative to surrounding structure, bottom,left=0,0
LLRect mRect;
U32 mReshapeFlags;
child_tab_order_t mCtrlOrder;
S32 mDefaultTabGroup;
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.
LLString mToolTipMsg; // isNull() is true if none.
U8 mSoundFlags;
BOOL mSaveToXML;
BOOL mIsFocusRoot;
public:
LLViewHandle mViewHandle;
BOOL mLastVisible;
BOOL mRenderInFastFrame;
BOOL mSpanChildren;
private:
BOOL mVisible;
BOOL mHidden; // Never show (generally for replacement text only)
S32 mNextInsertionOrdinal;
protected:
static LLWindow* sWindow; // All root views must know about their window.
public:
static BOOL sDebugRects; // Draw debug rects behind everything.
static BOOL sDebugKeys;
static S32 sDepth;
static LLView* sFastFrameView;
static BOOL sDebugMouseHandling;
static LLString sMouseHandlerMessage;
static S32 sSelectID;
static BOOL sEditingUI;
static LLView* sEditingUIView;
static S32 sLastLeftXML;
static S32 sLastBottomXML;
static std::map<LLViewHandle,LLView*> sViewHandleMap;
static BOOL sForceReshape;
public:
static LLView* getViewByHandle(LLViewHandle handle);
static BOOL deleteViewByHandle(LLViewHandle handle);
public:
LLView();
LLView(const LLString& name, BOOL mouse_opaque);
LLView(const LLString& name, const LLRect& rect, BOOL mouse_opaque, U32 follows=FOLLOWS_NONE);
virtual ~LLView();
// Hack to support LLFocusMgr
virtual BOOL isView();
// 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();
//
// MANIPULATORS
//
void setMouseOpaque( BOOL b );
void setToolTip( const LLString& msg );
virtual void setRect(const LLRect &rect);
void setFollows(U32 flags);
// deprecated, use setFollows() with FOLLOWS_LEFT | FOLLOWS_TOP, etc.
void setFollowsNone();
void setFollowsLeft();
void setFollowsTop();
void setFollowsRight();
void setFollowsBottom();
void setFollowsAll();
void setSoundFlags(U8 flags);
void setName(LLString name);
void setSpanChildren( BOOL span_children );
const LLString& getToolTip();
void sendChildToFront(LLView* child);
void sendChildToBack(LLView* child);
void moveChildToFrontOfTabGroup(LLUICtrl* child);
void addChild(LLView* view, S32 tab_group = 0);
void addChildAtEnd(LLView* view, S32 tab_group = 0);
// remove the specified child from the view, and set it's parent to NULL.
void removeChild( LLView* view );
virtual void addCtrl( LLUICtrl* ctrl, S32 tab_group);
virtual void addCtrlAtEnd( LLUICtrl* ctrl, S32 tab_group);
virtual void removeCtrl( LLUICtrl* ctrl);
child_tab_order_t getCtrlOrder() const { return mCtrlOrder; }
ctrl_list_t getCtrlList() const;
ctrl_list_t getCtrlListSorted() const;
S32 getDefaultTabGroup() const;
BOOL isInVisibleChain() const;
BOOL isInEnabledChain() const;
BOOL isFocusRoot() const;
LLView* findRootMostFocusRoot();
virtual BOOL canFocusChildren() const;
class LLFocusRootsFilter : public LLQueryFilter, public LLSingleton<LLFocusRootsFilter>
{
/*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const
{
return filterResult_t(view->isCtrl() && view->isFocusRoot(), !view->isFocusRoot());
}
};
virtual BOOL focusNextRoot();
virtual BOOL focusPrevRoot();
virtual BOOL focusNextItem(BOOL text_entry_only);
virtual BOOL focusPrevItem(BOOL text_entry_only);
virtual BOOL focusFirstItem(BOOL prefer_text_fields = FALSE );
virtual BOOL focusLastItem(BOOL prefer_text_fields = 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();
// by default, does nothing
virtual void setTentative(BOOL b);
// by default, returns false
virtual BOOL getTentative() const;
virtual void setAllChildrenEnabled(BOOL b);
virtual void setEnabled(BOOL enabled);
virtual void setVisible(BOOL visible);
virtual void setHidden(BOOL hidden); // Never show (replacement text)
// by default, does nothing and returns false
virtual BOOL setLabelArg( const LLString& key, const LLString& text );
virtual void onVisibilityChange ( BOOL curVisibilityIn );
void pushVisible(BOOL visible) { mLastVisible = mVisible; setVisible(visible); }
void popVisible() { setVisible(mLastVisible); mLastVisible = TRUE; }
//
// ACCESSORS
//
BOOL getMouseOpaque() const { return mMouseOpaque; }
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 getScreenRect() const;
const LLRect getLocalRect() const;
virtual const LLRect getSnapRect() const { return mRect; }
virtual LLRect getRequiredRect(); // Get required size for this object. 0 for width/height means don't care.
virtual void updateRect(); // apply procedural updates to own rectangle
LLView* getRootView();
LLView* getParent() const { return mParentView; }
LLView* getFirstChild() { return (mChildList.empty()) ? NULL : *(mChildList.begin()); }
S32 getChildCount() const { return (S32)mChildList.size(); }
template<class _Pr3> void sortChildren(_Pr3 _Pred) { mChildList.sort(_Pred); }
BOOL hasAncestor(LLView* parentp);
BOOL hasChild(const LLString& childname, BOOL recurse = FALSE) const;
BOOL childHasKeyboardFocus( const LLString& childname ) const;
//
// 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 );
BOOL translateIntoRect( const LLRect& constraint, BOOL allow_partial_outside );
void setOrigin( S32 x, S32 y ) { mRect.translate( x - mRect.mLeft, y - mRect.mBottom ); }
LLView* findSnapRect(LLRect& new_rect, const LLCoordGL& mouse_dir, LLView::ESnapType snap_type, S32 threshold, S32 padding = 0);
LLView* findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_dir, ESnapEdge snap_edge, ESnapType snap_type, S32 threshold, S32 padding = 0);
// Defaults to other_view->getVisible()
virtual BOOL canSnapTo(LLView* other_view);
virtual void snappedTo(LLView* snap_view);
virtual BOOL handleKey(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,
LLString& tooltip_msg);
// 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 handleDoubleClick(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
// Default behavior is to pass the tooltip event to children,
// then display mToolTipMsg if no child handled it.
/*virtual*/ BOOL handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect);
LLString getShowNamesToolTip();
virtual void draw();
void drawDebugRect();
void drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0);
virtual const LLString& getName() const;
virtual EWidgetType getWidgetType() const = 0;
virtual LLString getWidgetTag() const = 0;
virtual LLXMLNodePtr getXML(bool save_children = true) const;
static U32 createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, const LLRect &required_rect = LLRect());
virtual void initFromXML(LLXMLNodePtr node, LLView* parent);
static LLFontGL* selectFont(LLXMLNodePtr node);
static LLFontGL::HAlign selectFontHAlign(LLXMLNodePtr node);
static LLFontGL::VAlign selectFontVAlign(LLXMLNodePtr node);
static LLFontGL::StyleFlags selectFontStyle(LLXMLNodePtr node);
// Some widgets, like close box buttons, don't need to be saved
BOOL getSaveToXML() const { return mSaveToXML; }
void setSaveToXML(BOOL b) { mSaveToXML = b; }
// Only saves color if different from default setting.
static void addColorXML(LLXMLNodePtr node, const LLColor4& color,
const LLString& xml_name, const LLString& control_name);
static void saveColorToXML(std::ostream& out, const LLColor4& color,
const LLString& xml_name, const LLString& control_name,
const LLString& indent); // DEPRECATED
// Escapes " (quot) ' (apos) & (amp) < (lt) > (gt)
//static LLString escapeXML(const LLString& xml);
static LLWString escapeXML(const LLWString& xml);
//same as above, but wraps multiple lines in quotes and prepends
//indent as leading white space on each line
static LLString escapeXML(const LLString& xml, LLString& indent);
// 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 LLCtrlQuery & getTabOrderQuery();
// return query for iterating over focus roots in tab order
static const LLCtrlQuery & getFocusRootsQuery();
BOOL getEnabled() const { return mEnabled; }
BOOL getVisible() const { return mVisible && !mHidden; }
U8 getSoundFlags() const { return mSoundFlags; }
// Default to no action
virtual void onFocusLost();
virtual void onFocusReceived();
BOOL parentPointInView(S32 x, S32 y) const { return mRect.pointInRect( x, y ); }
BOOL pointInView(S32 x, S32 y) const { return mRect.localPointInRect( x, y ); }
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 BOOL localPointToOtherView( S32 x, S32 y, S32 *other_x, S32 *other_y, LLView* other_view);
virtual void screenRectToLocal( const LLRect& screen, LLRect* local ) const;
virtual void localRectToScreen( const LLRect& local, LLRect* screen ) const;
virtual BOOL localRectToOtherView( const LLRect& local, LLRect* other, LLView* other_view ) const;
void setRenderInFastFrame(BOOL render) { mRenderInFastFrame = render; }
virtual LLView* getRootMostFastFrameView();
static LLWindow* getWindow(void);
// Listener dispatching functions (Dispatcher deletes pointers to listeners on deregistration or destruction)
LLSimpleListener* getListenerByName(const LLString &callback_name);
void registerEventListener(LLString name, LLSimpleListener* function);
void deregisterEventListener(LLString name);
LLString findEventListener(LLSimpleListener *listener) const;
void addListenerToControl(LLEventDispatcher *observer, const LLString& name, LLSD filter, LLSD userdata);
virtual LLView* getChildByName(const LLString& name, BOOL recurse = FALSE) const;
void addBoolControl(LLString name, bool initial_value);
LLControlBase *getControl(LLString name);
virtual LLControlBase *findControl(LLString name);
void setControlValue(const LLSD& value);
virtual void setControlName(const LLString& control, LLView *context);
virtual LLString getControlName() const;
virtual bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata);
virtual void setValue(const LLSD& value);
const child_list_t* getChildList() const { return &mChildList; }
protected:
virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent);
virtual BOOL handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent);
LLView* childrenHandleKey(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,
LLString& 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* childrenHandleDoubleClick(S32 x, S32 y, MASK mask);
LLView* childrenHandleScrollWheel(S32 x, S32 y, S32 clicks);
LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask);
LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask);
typedef std::map<LLString, LLSimpleListener*> dispatch_list_t;
dispatch_list_t mDispatchList;
protected:
typedef std::map<LLString, LLControlBase*> control_map_t;
control_map_t mFloaterControls;
LLString mControlName;
friend class LLUICtrlFactory;
};
class LLCompareByTabOrder
{
public:
LLCompareByTabOrder(LLView::child_tab_order_t order);
virtual ~LLCompareByTabOrder() {}
bool operator() (const LLView* const a, const LLView* const b) const;
protected:
virtual bool compareTabOrders(const LLView::tab_order_t & a, const LLView::tab_order_t & b) const;
LLView::child_tab_order_t mTabOrder;
};
#endif