Files
SingularityViewer/indra/llui/llview.h
Lirusaito 2653567d82 Sync with alchemy
Moves some constants out of llavatarconstants.h
8ebf8f4608bd: Change various const constants to constexpr
e07d5d43ba30: CID-143595
30b6935fc66d: CID-143595
acc96f9051cb: Fix a memory leak in viewer side baking initial wearable setup
Sync llmodel.*

Changesets assimilated:
f8f7706c2902: CID-143554 - fix out of bounds access
223eb65adce4: CID-143554 - Chase
2ceb49aaa133: CID-42838, CID-42930, CID-42933, CID-42938, CID-42940, CID-42945, CID-42948, CID-56111, CID-83907
d220005d9f23: Missing null check before deref
31dbb0f3b6ee: CID-42571 CID-42576 CID-42578
49caf082e65c: change unordered_map to flat_map
Doesn't cause as many problems as a hashmap when it comes to assumptions in the
LLUI system.
f93f5e881484: "update" linux cef
downgrade to fix javascript problems
cba818dd9269: Various null checks and etc.
1b4c6bc483bb: CID-42847, CID-42854, CID-42886, CID-42921, CID-42922, CID-42923, CID-42924, CID-42925,
CID-42927, CID-42928, CID-83871, CID-83876, CID-83878, CID-83880, CID-83900, CID-143573
0fe90cd9ec24: Various file size related things
a79f6f653dca: CID-42918 - Initialize member pointers in LLFloaterGodTools
0b70d600d978: Tweak LLFloaterBuyLand initializations
e8b173ffe813: CID-42854 - Additional fix to LLDrawInfo
b5d745cf3fde: Fix signage
4f2e2f384781: Initialize and cleanup various class member variables.
CID-42899, CID-42900, CID-42902, CID-42903, CID-42904, CID-42905, CID-42909, CID-42910,
CID-42911, CID-42912, CID-42913, CID-42967, CID-83853, CID-83898, CID-83890, CID-143584
9851a3e39b4c: Fix platform specific include directories
5c074e84f1be: Initialize and clenaup various more class member variables.
CID-42885, CID-42853, CID-42894, CID-42895, CID-42896, CID-83908, CID-143574, CID-143575,
CID-143576, CID-143576, CID-143578
ac262854ac92: Brace sub-object in initialization to make our intentions clear to clang
358da477d4c1: More double brace init
c3850119314a: Initialize various member pointers in panels
CID-83902, CID-83903, CID-83905, CID-83909, CID-83911, CID-83912, CID-143572
2016-03-30 21:06:47 -04:00

829 lines
28 KiB
C++

/**
* @file llview.h
* @brief Container for other views, anything that draws.
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/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 "llcoord.h"
#include "llfontgl.h"
#include "llhandle.h"
#include "llmortician.h"
#include "llmousehandler.h"
#include "llnametable.h"
#include "llsd.h"
#include "llstring.h"
#include "llrect.h"
#include "llui.h"
#include "lluistring.h"
#include "lluixmltags.h"
#include "llviewquery.h"
#include "llxmlnode.h"
#include "stdenums.h"
#include "lluistring.h"
#include "llcursortypes.h"
#include "llinitparam.h"
#include "lltreeiterators.h"
#include "llfocusmgr.h"
#include <boost/container/flat_map.hpp> // <alchemy/>
#include "ailist.h"
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 LLUICtrlFactory;
// maps xml strings to widget classes
class LLWidgetClassRegistry : public LLSingleton<LLWidgetClassRegistry>
{
friend class LLSingleton<LLWidgetClassRegistry>;
public:
typedef LLView* (*factory_func_t)(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
typedef std::map<std::string, factory_func_t> factory_map_t;
void registerCtrl(const std::string& xml_tag, factory_func_t function);
BOOL isTagRegistered(const std::string& xml_tag);
factory_func_t getCreatorFunc(const std::string& xml_tag);
// get (first) xml tag for a given class
template <class T> std::string getTag()
{
factory_map_t::iterator it;
for(it = mCreatorFunctions.begin(); it != mCreatorFunctions.end(); ++it)
{
if (it->second == T::fromXML)
{
return it->first;
}
}
return "";
}
private:
LLWidgetClassRegistry();
virtual ~LLWidgetClassRegistry() {};
typedef std::set<std::string> ctrl_name_set_t;
ctrl_name_set_t mUICtrlNames;
// map of xml tags to widget creator functions
factory_map_t mCreatorFunctions;
};
template<class T>
class LLRegisterWidget
{
public:
LLRegisterWidget(const std::string& tag)
{
LLWidgetClassRegistry* registry = LLWidgetClassRegistry::getInstance();
if (registry->isTagRegistered(tag))
{
//error!
LL_ERRS() << "Widget named " << tag << " already registered!" << LL_ENDL;
}
else
{
registry->registerCtrl(tag, T::fromXML);
}
}
};
// 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:
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();
};
void initFromParams(const LLView::Params&);
template<typename T>
struct CachedUICtrl
{
CachedUICtrl():mPtr(NULL){}
T* connect(LLView* parent,const char* pName){return mPtr = parent->getChild<T>(pName);}
T* operator->(){return mPtr;}
operator T*() const{return mPtr;}
T* mPtr;
};
protected:
LLView(const LLView::Params&);
//friend class LLUICtrlFactory;
private:
void init(const LLView::Params&);
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 AIList<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<class 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;
LLView();
LLView(const std::string& name, BOOL mouse_opaque);
LLView(const std::string& name, const LLRect& rect, BOOL mouse_opaque, U32 follows=FOLLOWS_NONE);
virtual ~LLView();
// Hack to support LLFocusMgr (from LLMouseHandler)
/*virtual*/ BOOL isView() const;
// 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; }
const std::string& getToolTip() const { return mToolTipMsg.getString(); }
void sendChildToFront(LLView* child);
void sendChildToBack(LLView* child);
void moveChildToFrontOfTabGroup(LLUICtrl* child);
void moveChildToBackOfTabGroup(LLUICtrl* 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& getCtrlOrder() const { return mCtrlOrder; }
ctrl_list_t getCtrlList() const;
ctrl_list_t getCtrlListSorted() const;
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
// at handling them. (eg. the script editor)
virtual bool hasAccelerators() const { return false; }
virtual void deleteAllChildren();
virtual void setTentative(BOOL b);
virtual BOOL getTentative() const;
void setAllChildrenEnabled(BOOL b);
virtual void setVisible(BOOL visible);
const BOOL& getVisible() const { return mVisible; }
virtual void setEnabled(BOOL enabled);
BOOL getEnabled() const { return mEnabled; }
U8 getSoundFlags() const { return mSoundFlags; }
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
virtual void handleVisibilityChange ( BOOL new_visibility );
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;
// 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, BOOL allow_partial_outside );
BOOL translateIntoRectWithExclusion( const LLRect& inside, const LLRect& exclude, BOOL allow_partial_outside );
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);
std::string getShowNamesToolTip();
virtual void draw();
void parseFollowsFlags(const LLView::Params& params);
virtual LLXMLNodePtr getXML(bool save_children = true) const;
//FIXME: make LLView non-instantiable from XML
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory);
virtual void initFromXML(LLXMLNodePtr node, LLView* parent);
void parseFollowsFlags(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; }
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, LLView* other_view) const;
BOOL localRectToOtherView( const LLRect& local, LLRect* other, LLView* other_view ) const;
void screenRectToLocal( const LLRect& screen, LLRect* local ) const;
void localRectToScreen( const LLRect& local, LLRect* screen ) const;
// Listener dispatching functions (Dispatcher deletes pointers to listeners on deregistration or destruction)
LLOldEvents::LLSimpleListener* getListenerByName(const std::string& callback_name);
void registerEventListener(std::string name, LLOldEvents::LLSimpleListener* function);
void deregisterEventListener(std::string name);
typedef boost::signals2::signal<void (LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)> event_signal_t;
void registerEventListener(std::string name, event_signal_t::slot_type &cb);
std::string findEventListener(LLOldEvents::LLSimpleListener *listener) const;
void addListenerToControl(LLOldEvents::LLEventDispatcher *observer, const std::string& name, LLSD filter, LLSD userdata);
void addBoolControl(const std::string& name, bool initial_value);
LLControlVariable *getControl(const std::string& name);
LLControlVariable *findControl(const std::string& name);
bool setControlValue(const LLSD& value);
virtual void setControlName(const std::string& control, LLView *context);
virtual std::string getControlName() const { return mControlName; }
// virtual bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
virtual void setValue(const LLSD& value);
virtual LLSD getValue() const;
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(); }
boost::container::flat_map<std::string, LLView*> mChildHashMap; // <alchemy/>
// 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 handleRightMouseDown(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect); // Display mToolTipMsg if no child handles it.
/*virtual*/ const std::string& getName() const;
/*virtual*/ void onMouseCaptureLost();
/*virtual*/ BOOL hasMouseCapture();
/*virtual*/ BOOL isView(); // Hack to support LLFocusMgr
/*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);
template <class T> T* findChild(const std::string& name)
{
return getChild<T>(name,true,false);
}
template <class T> T* getChild(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const
{
LLView* child = getChildView(name, recurse, FALSE);
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;
}
if (create_if_missing)
{
// create dummy widget instance here
result = createDummyWidget<T>(name);
}
}
return result;
}
template <class T> T& getChildRef(const std::string& name, BOOL recurse = TRUE) const
{
return *getChild<T>(name, recurse, TRUE);
}
virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const;
template <class T> T* createDummyWidget(const std::string& name) const
{
T* widget = getDummyWidget<T>(name);
if (!widget)
{
// get xml tag name corresponding to requested widget type (e.g. "button")
std::string xml_tag = LLWidgetClassRegistry::getInstance()->getTag<T>();
if (xml_tag.empty())
{
LL_WARNS() << "No xml tag registered for this class " << LL_ENDL;
return NULL;
}
// create dummy xml node (<button name="foo"/>)
LLXMLNodePtr new_node_ptr = new LLXMLNode(xml_tag.c_str(), FALSE);
new_node_ptr->createChild("name", TRUE)->setStringValue(name);
widget = dynamic_cast<T*>(createWidget(new_node_ptr));
if (widget)
{
// need non-const to update private dummy widget cache
LL_WARNS() << "Making dummy " << xml_tag << " named " << name << " in " << getName() << LL_ENDL;
mDummyWidgets.insert(std::make_pair(name, widget));
}
else
{
// dynamic cast will fail if T::fromXML only registered for base class
LL_WARNS() << "Failed to create dummy widget of requested type " << LL_ENDL;
return NULL;
}
}
return widget;
}
template <class T> T* getDummyWidget(const std::string& name) const
{
dummy_widget_map_t::const_iterator found_it = mDummyWidgets.find(name);
if (found_it == mDummyWidgets.end())
{
return NULL;
}
return dynamic_cast<T*>(found_it->second);
}
LLView* createWidget(LLXMLNodePtr xml_node) const;
// statics
static U32 createRect(LLXMLNodePtr node, LLRect &rect, LLView* parent_view, const LLRect &required_rect = LLRect());
static LLFontGL* selectFont(LLXMLNodePtr node);
static LLFontGL::HAlign selectFontHAlign(LLXMLNodePtr node);
static LLFontGL::VAlign selectFontVAlign(LLXMLNodePtr node);
static LLFontGL::StyleFlags selectFontStyle(LLXMLNodePtr node);
// Only saves color if different from default setting.
static void addColorXML(LLXMLNodePtr node, const LLColor4& color,
const char* xml_name, const char* control_name);
// Escapes " (quot) ' (apos) & (amp) < (lt) > (gt)
//static std::string escapeXML(const std::string& 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 std::string escapeXML(const std::string& xml, std::string& indent);
// focuses the item in the list after the currently-focused item, wrapping if necessary
static BOOL focusNext(viewList_t& result);
// focuses the item in the list before the currently-focused item, wrapping if necessary
static BOOL focusPrev(viewList_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();
static BOOL deleteViewByHandle(LLHandle<LLView> handle);
static LLWindow* getWindow(void) { return LLUI::sWindow; }
virtual void handleReshape(const LLRect& rect, bool by_user);
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual BOOL handleKeyUpHere(KEY key, MASK mask);
virtual BOOL handleUnicodeCharHere(llwchar uni_char);
//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();
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* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask);
LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask);
static bool controlListener(const LLSD& newvalue, LLHandle<LLView> handle, std::string type);
typedef std::map<std::string, LLControlVariable*> control_map_t;
control_map_t mFloaterControls;
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 mName;
U32 mReshapeFlags;
child_tab_order_t mCtrlOrder;
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 mSaveToXML;
BOOL mIsFocusRoot;
BOOL mUseBoundingRect; // hit test against bounding rectangle that includes all child elements
BOOL mLastVisible;
S32 mNextInsertionOrdinal;
bool mInDraw;
private:
static LLWindow* sWindow; // All root views must know about their window.
typedef std::map<std::string, LLPointer<LLOldEvents::LLSimpleListener> > dispatch_list_t;
dispatch_list_t mDispatchList;
std::string mControlName;
typedef std::map<std::string, LLView*> dummy_widget_map_t;
mutable dummy_widget_map_t mDummyWidgets;
boost::signals2::connection mControlConnection;
ECursorType mHoverCursor;
// 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;
};
public:
static BOOL sDebugRects; // Draw debug rects behind everything.
static BOOL sDebugKeys;
static S32 sDepth;
static BOOL sDebugMouseHandling;
static std::string sMouseHandlerMessage;
static S32 sSelectID;
static BOOL sEditingUI;
static LLView* sEditingUIView;
static S32 sLastLeftXML;
static S32 sLastBottomXML;
static BOOL sForceReshape;
};
class LLCompareByTabOrder
{
public:
LLCompareByTabOrder(LLView::child_tab_order_t order) : mTabOrder(order) {}
virtual ~LLCompareByTabOrder() {}
bool operator() (const LLView* const a, const LLView* const b) const;
private:
virtual bool compareTabOrders(const LLView::tab_order_t & a, const LLView::tab_order_t & b) const { return a < b; }
LLView::child_tab_order_t mTabOrder;
};
#endif //LL_LLVIEW_H