Context menu appears for text-entry boxes. Temp workaround for shutdown crash. Removed extra 'Wear' entry from inventory context menu. Fixed separators not appearing in inventory context menu. mouse_opaque actually 'blocks' mouse events on occluded ui elements.

This commit is contained in:
Shyotl
2012-03-02 23:30:57 -06:00
parent 500135941a
commit 355883aa5c
12 changed files with 427 additions and 579 deletions

View File

@@ -207,7 +207,7 @@ LLButton::LLButton(const std::string& name, const LLRect& rect,
{
// user-specified image - don't use fixed borders unless requested
mImageSelected = LLUI::getUIImage(selected_image_name);
mImageDisabled = mImageSelected;
mImageDisabledSelected = mImageSelected;
mFadeWhenDisabled = TRUE;
//mScaleImage = FALSE;

View File

@@ -430,6 +430,27 @@ void LLFloater::initFloater(const std::string& title,
}
}
void LLFloater::enableResizeCtrls(bool enable, bool width, bool height)
{
mResizeBar[LLResizeBar::LEFT]->setVisible(enable && width);
mResizeBar[LLResizeBar::LEFT]->setEnabled(enable && width);
mResizeBar[LLResizeBar::TOP]->setVisible(enable && height);
mResizeBar[LLResizeBar::TOP]->setEnabled(enable && height);
mResizeBar[LLResizeBar::RIGHT]->setVisible(enable && width);
mResizeBar[LLResizeBar::RIGHT]->setEnabled(enable && width);
mResizeBar[LLResizeBar::BOTTOM]->setVisible(enable && height);
mResizeBar[LLResizeBar::BOTTOM]->setEnabled(enable && height);
for (S32 i = 0; i < 4; ++i)
{
mResizeHandle[i]->setVisible(enable && width && height);
mResizeHandle[i]->setEnabled(enable && width && height);
}
}
// virtual
LLFloater::~LLFloater()
{
@@ -1641,6 +1662,7 @@ void LLFloater::setCanResize(BOOL can_resize)
mMinHeight,
LLResizeHandle::LEFT_TOP );
addChild(mResizeHandle[3]);
enableResizeCtrls(can_resize);
}
mResizable = can_resize;
}

View File

@@ -251,6 +251,7 @@ public:
static BOOL getEditModeEnabled() { return sEditModeEnabled; }
static LLMultiFloater* getFloaterHost() {return sHostp; }
void enableResizeCtrls(bool enable, bool width = true, bool height = true);
protected:
virtual void bringToFront(S32 x, S32 y);

View File

@@ -1951,12 +1951,17 @@ void LLMenuGL::parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory
submenu->updateParent(parent);
}
}
else if (child->hasName(LL_MENU_ITEM_CALL_GL_TAG) ||
child->hasName(LL_MENU_ITEM_CHECK_GL_TAG) ||
child->hasName(LL_MENU_ITEM_SEPARATOR_GL_TAG))
else if (child->hasName(LL_MENU_ITEM_SEPARATOR_GL_TAG))
{
LLMenuItemGL *item = NULL;
std::string item_name;
child->getAttributeString("name", item_name);
LLMenuItemGL* separator = new LLMenuItemSeparatorGL(item_name);
addChild(separator);
}
else if(child->hasName(LL_MENU_ITEM_CALL_GL_TAG) ||
child->hasName(LL_MENU_ITEM_CHECK_GL_TAG))
{
// ITEM
std::string type;
std::string item_name;
std::string source_label;
@@ -1966,7 +1971,7 @@ void LLMenuGL::parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory
child->getAttributeString("type", type);
child->getAttributeString("name", item_name);
child->getAttributeString("label", source_label);
// parse jump key out of label
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
boost::char_separator<char> sep("_");
@@ -1983,242 +1988,225 @@ void LLMenuGL::parseChildXML(LLXMLNodePtr child, LLView *parent, LLUICtrlFactory
++token_count;
}
if (child->hasName(LL_MENU_ITEM_SEPARATOR_GL_TAG))
MASK mask = 0;
#ifdef LL_DARWIN
// See if this Mac accelerator should really use the ctrl key and not get mapped to cmd
BOOL useMacCtrl = FALSE;
child->getAttributeBOOL("useMacCtrl", useMacCtrl);
#endif // LL_DARWIN
std::string shortcut;
child->getAttributeString("shortcut", shortcut);
if (shortcut.find("control") != shortcut.npos)
{
addSeparator();
}
else
{
// ITEM
if (child->hasName(LL_MENU_ITEM_CALL_GL_TAG) ||
child->hasName(LL_MENU_ITEM_CHECK_GL_TAG))
#ifdef LL_DARWIN
if ( useMacCtrl )
{
MASK mask = 0;
#ifdef LL_DARWIN
// See if this Mac accelerator should really use the ctrl key and not get mapped to cmd
BOOL useMacCtrl = FALSE;
child->getAttributeBOOL("useMacCtrl", useMacCtrl);
mask |= MASK_MAC_CONTROL;
}
#endif // LL_DARWIN
std::string shortcut;
child->getAttributeString("shortcut", shortcut);
if (shortcut.find("control") != shortcut.npos)
{
#ifdef LL_DARWIN
if ( useMacCtrl )
{
mask |= MASK_MAC_CONTROL;
}
#endif // LL_DARWIN
mask |= MASK_CONTROL;
}
if (shortcut.find("alt") != shortcut.npos)
{
mask |= MASK_ALT;
}
if (shortcut.find("shift") != shortcut.npos)
{
mask |= MASK_SHIFT;
}
S32 pipe_pos = shortcut.rfind("|");
std::string key_str = shortcut.substr(pipe_pos+1);
mask |= MASK_CONTROL;
}
if (shortcut.find("alt") != shortcut.npos)
{
mask |= MASK_ALT;
}
if (shortcut.find("shift") != shortcut.npos)
{
mask |= MASK_SHIFT;
}
S32 pipe_pos = shortcut.rfind("|");
std::string key_str = shortcut.substr(pipe_pos+1);
KEY key = KEY_NONE;
LLKeyboard::keyFromString(key_str, &key);
KEY key = KEY_NONE;
LLKeyboard::keyFromString(key_str, &key);
LLMenuItemCallGL *new_item;
LLXMLNodePtr call_child;
LLMenuItemCallGL *new_item;
LLXMLNodePtr call_child;
if (child->hasName(LL_MENU_ITEM_CHECK_GL_TAG))
if (child->hasName(LL_MENU_ITEM_CHECK_GL_TAG))
{
std::string control_name;
child->getAttributeString("control_name", control_name);
new_item = new LLMenuItemCheckGL(item_name, item_label, 0, 0, control_name, parent, 0, key, mask);
for (call_child = child->getFirstChild(); call_child.notNull(); call_child = call_child->getNextSibling())
{
if (call_child->hasName("on_check"))
{
std::string callback_name;
std::string control_name;
child->getAttributeString("control_name", control_name);
new_item = new LLMenuItemCheckGL(item_name, item_label, 0, 0, control_name, parent, 0, key, mask);
for (call_child = child->getFirstChild(); call_child.notNull(); call_child = call_child->getNextSibling())
if (call_child->hasAttribute("function"))
{
if (call_child->hasName("on_check"))
{
std::string callback_name;
std::string control_name;
if (call_child->hasAttribute("function"))
{
call_child->getAttributeString("function", callback_name);
control_name = callback_name;
std::string callback_data = item_name;
if (call_child->hasAttribute("userdata"))
{
call_child->getAttributeString("userdata", callback_data);
if (!callback_data.empty())
{
control_name = llformat("%s(%s)", callback_name.c_str(), callback_data.c_str());
}
}
LLSD userdata;
userdata["control"] = control_name;
userdata["data"] = callback_data;
LLSimpleListener* callback = parent->getListenerByName(callback_name);
if (!callback)
{
lldebugs << "Ignoring \"on_check\" \"" << item_name << "\" because \"" << callback_name << "\" is not registered" << llendl;
continue;
}
new_item->addListener(callback, "on_build", userdata);
}
else if (call_child->hasAttribute("control"))
{
call_child->getAttributeString("control", control_name);
}
else
{
continue;
}
LLControlVariable *control = parent->findControl(control_name);
if (!control)
{
parent->addBoolControl(control_name, FALSE);
}
((LLMenuItemCheckGL*)new_item)->setCheckedControl(control_name, parent);
}
}
}
else
{
new_item = new LLMenuItemCallGL(item_name, item_label, 0, 0, 0, 0, key, mask);
}
for (call_child = child->getFirstChild(); call_child.notNull(); call_child = call_child->getNextSibling())
{
if (call_child->hasName("on_click"))
{
std::string callback_name;
call_child->getAttributeString("function", callback_name);
control_name = callback_name;
std::string callback_data = item_name;
if (call_child->hasAttribute("userdata"))
{
call_child->getAttributeString("userdata", callback_data);
if (!callback_data.empty())
{
control_name = llformat("%s(%s)", callback_name.c_str(), callback_data.c_str());
}
}
LLSD userdata;
userdata["control"] = control_name;
userdata["data"] = callback_data;
LLSimpleListener* callback = parent->getListenerByName(callback_name);
if (!callback)
{
lldebugs << "Ignoring \"on_click\" \"" << item_name << "\" because \"" << callback_name << "\" is not registered" << llendl;
lldebugs << "Ignoring \"on_check\" \"" << item_name << "\" because \"" << callback_name << "\" is not registered" << llendl;
continue;
}
new_item->addListener(callback, "on_click", callback_data);
new_item->addListener(callback, "on_build", userdata);
}
if (call_child->hasName("on_enable"))
else if (call_child->hasAttribute("control"))
{
std::string callback_name;
std::string control_name;
if (call_child->hasAttribute("function"))
{
call_child->getAttributeString("function", callback_name);
control_name = callback_name;
std::string callback_data;
if (call_child->hasAttribute("userdata"))
{
call_child->getAttributeString("userdata", callback_data);
if (!callback_data.empty())
{
control_name = llformat("%s(%s)", callback_name.c_str(), callback_data.c_str());
}
}
LLSD userdata;
userdata["control"] = control_name;
userdata["data"] = callback_data;
LLSimpleListener* callback = parent->getListenerByName(callback_name);
if (!callback)
{
lldebugs << "Ignoring \"on_enable\" \"" << item_name << "\" because \"" << callback_name << "\" is not registered" << llendl;
continue;
}
new_item->addListener(callback, "on_build", userdata);
}
else if (call_child->hasAttribute("control"))
{
call_child->getAttributeString("control", control_name);
}
else
{
continue;
}
new_item->setEnabledControl(control_name, parent);
call_child->getAttributeString("control", control_name);
}
if (call_child->hasName("on_visible"))
else
{
std::string callback_name;
std::string control_name;
if (call_child->hasAttribute("function"))
{
call_child->getAttributeString("function", callback_name);
control_name = callback_name;
std::string callback_data;
if (call_child->hasAttribute("userdata"))
{
call_child->getAttributeString("userdata", callback_data);
if (!callback_data.empty())
{
control_name = llformat("%s(%s)", callback_name.c_str(), callback_data.c_str());
}
}
LLSD userdata;
userdata["control"] = control_name;
userdata["data"] = callback_data;
LLSimpleListener* callback = parent->getListenerByName(callback_name);
if (!callback)
{
lldebugs << "Ignoring \"on_visible\" \"" << item_name << "\" because \"" << callback_name << "\" is not registered" << llendl;
continue;
}
new_item->addListener(callback, "on_build", userdata);
}
else if (call_child->hasAttribute("control"))
{
call_child->getAttributeString("control", control_name);
}
else
{
continue;
}
new_item->setVisibleControl(control_name, parent);
continue;
}
LLControlVariable *control = parent->findControl(control_name);
if (!control)
{
parent->addBoolControl(control_name, FALSE);
}
((LLMenuItemCheckGL*)new_item)->setCheckedControl(control_name, parent);
}
item = new_item;
item->setLabel(item_label);
if (jump_key != KEY_NONE)
item->setJumpKey(jump_key);
}
if (item != NULL)
{
append(item);
}
}
else
{
new_item = new LLMenuItemCallGL(item_name, item_label, 0, 0, 0, 0, key, mask);
}
for (call_child = child->getFirstChild(); call_child.notNull(); call_child = call_child->getNextSibling())
{
if (call_child->hasName("on_click"))
{
std::string callback_name;
call_child->getAttributeString("function", callback_name);
std::string callback_data = item_name;
if (call_child->hasAttribute("userdata"))
{
call_child->getAttributeString("userdata", callback_data);
}
LLSimpleListener* callback = parent->getListenerByName(callback_name);
if (!callback)
{
lldebugs << "Ignoring \"on_click\" \"" << item_name << "\" because \"" << callback_name << "\" is not registered" << llendl;
continue;
}
new_item->addListener(callback, "on_click", callback_data);
}
if (call_child->hasName("on_enable"))
{
std::string callback_name;
std::string control_name;
if (call_child->hasAttribute("function"))
{
call_child->getAttributeString("function", callback_name);
control_name = callback_name;
std::string callback_data;
if (call_child->hasAttribute("userdata"))
{
call_child->getAttributeString("userdata", callback_data);
if (!callback_data.empty())
{
control_name = llformat("%s(%s)", callback_name.c_str(), callback_data.c_str());
}
}
LLSD userdata;
userdata["control"] = control_name;
userdata["data"] = callback_data;
LLSimpleListener* callback = parent->getListenerByName(callback_name);
if (!callback)
{
lldebugs << "Ignoring \"on_enable\" \"" << item_name << "\" because \"" << callback_name << "\" is not registered" << llendl;
continue;
}
new_item->addListener(callback, "on_build", userdata);
}
else if (call_child->hasAttribute("control"))
{
call_child->getAttributeString("control", control_name);
}
else
{
continue;
}
new_item->setEnabledControl(control_name, parent);
}
if (call_child->hasName("on_visible"))
{
std::string callback_name;
std::string control_name;
if (call_child->hasAttribute("function"))
{
call_child->getAttributeString("function", callback_name);
control_name = callback_name;
std::string callback_data;
if (call_child->hasAttribute("userdata"))
{
call_child->getAttributeString("userdata", callback_data);
if (!callback_data.empty())
{
control_name = llformat("%s(%s)", callback_name.c_str(), callback_data.c_str());
}
}
LLSD userdata;
userdata["control"] = control_name;
userdata["data"] = callback_data;
LLSimpleListener* callback = parent->getListenerByName(callback_name);
if (!callback)
{
lldebugs << "Ignoring \"on_visible\" \"" << item_name << "\" because \"" << callback_name << "\" is not registered" << llendl;
continue;
}
new_item->addListener(callback, "on_build", userdata);
}
else if (call_child->hasAttribute("control"))
{
call_child->getAttributeString("control", control_name);
}
else
{
continue;
}
new_item->setVisibleControl(control_name, parent);
}
}
new_item->setLabel(item_label);
if (jump_key != KEY_NONE)
new_item->setJumpKey(jump_key);
append(new_item);
}
}

View File

@@ -185,7 +185,8 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
if (mSnappingEnabled)
{
static LLCachedControl<S32> snap_margin (*LLUI::sConfigGroup,"SnapMargin", 0);
//static LLCachedControl<S32> snap_margin (*LLUI::sConfigGroup,"SnapMargin", 0);
S32 snap_margin = LLUI::sConfigGroup->getS32("SnapMargin");
switch( mSide )
{
case LEFT:

View File

@@ -46,7 +46,7 @@ const S32 RESIZE_BORDER_WIDTH = 3;
LLResizeHandle::LLResizeHandle( const std::string& name, const LLRect& rect, S32 min_width, S32 min_height, ECorner corner )
:
LLView( name, rect, TRUE ),
LLView( name, rect, FALSE ),
mDragLastScreenX( 0 ),
mDragLastScreenY( 0 ),
mLastMouseScreenX( 0 ),
@@ -205,7 +205,8 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
LLView* snap_view = NULL;
LLView* test_view = NULL;
static LLCachedControl<S32> snap_margin (*LLUI::sConfigGroup,"SnapMargin", 0);
//static LLCachedControl<S32> snap_margin (*LLUI::sConfigGroup,"SnapMargin", 0);
S32 snap_margin = LLUI::sConfigGroup->getS32("SnapMargin");
// now do snapping
switch(mCorner)
{

View File

@@ -188,18 +188,6 @@ void LLUICtrl::setFocus(BOOL b)
}
}
void LLUICtrl::onFocusReceived()
{
// trigger callbacks
LLFocusableElement::onFocusReceived();
}
void LLUICtrl::onFocusLost()
{
// trigger callbacks
LLFocusableElement::onFocusLost();
}
// virtual
void LLUICtrl::setTabStop( BOOL b )
{

View File

@@ -66,8 +66,6 @@ public:
/*virtual*/ void initFromXML(LLXMLNodePtr node, LLView* parent);
/*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const;
/*virtual*/ BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
/*virtual*/ void onFocusReceived();
/*virtual*/ void onFocusLost();
/*virtual*/ BOOL isCtrl() const;
// From LLFocusableElement

View File

@@ -79,6 +79,9 @@ LLView* LLView::sEditingUIView = NULL;
S32 LLView::sLastLeftXML = S32_MIN;
S32 LLView::sLastBottomXML = S32_MIN;
LLView::DrilldownFunc LLView::sDrilldown =
boost::bind(&LLView::pointInView, _1, _2, _3, HIT_TEST_USE_BOUNDING_RECT);
#if LL_DEBUG
BOOL LLView::sIsDrawing = FALSE;
#endif
@@ -664,18 +667,10 @@ void LLView::setSnappedTo(const LLView* snap_view)
BOOL LLView::handleHover(S32 x, S32 y, MASK mask)
{
BOOL handled = childrenHandleHover( x, y, mask ) != NULL;
if( !handled
&& blockMouseEvent(x, y) )
{
LLUI::sWindow->setCursor(mHoverCursor);
lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;
handled = TRUE;
}
return handled;
return childrenHandleHover( x, y, mask ) != NULL;
}
std::string LLView::getShowNamesToolTip()
{
LLView* view = getParent();
@@ -704,7 +699,6 @@ std::string LLView::getShowNamesToolTip()
return "/" + tool_tip;
}
BOOL LLView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen)
{
BOOL handled = FALSE;
@@ -767,6 +761,128 @@ BOOL LLView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_s
return handled;
}
bool LLView::visibleAndContains(S32 local_x, S32 local_y)
{
return sDrilldown(this, local_x, local_y)
&& getVisible();
}
bool LLView::visibleEnabledAndContains(S32 local_x, S32 local_y)
{
return visibleAndContains(local_x, local_y)
&& getEnabled();
}
void LLView::logMouseEvent()
{
if (sDebugMouseHandling)
{
sMouseHandlerMessage = std::string("/") + mName + sMouseHandlerMessage;
}
}
template <typename METHOD, typename CHARTYPE>
LLView* LLView::childrenHandleCharEvent(const std::string& desc, const METHOD& method,
CHARTYPE c, MASK mask)
{
if ( getVisible() && getEnabled() )
{
BOOST_FOREACH(LLView* viewp, mChildList)
{
if ((viewp->*method)(c, mask, TRUE))
{
if (LLView::sDebugKeys)
{
llinfos << desc << " handled by " << viewp->getName() << llendl;
}
return viewp;
}
}
}
return NULL;
}
// XDATA might be MASK, or S32 clicks
template <typename METHOD, typename XDATA>
LLView* LLView::childrenHandleMouseEvent(const METHOD& method, S32 x, S32 y, XDATA extra, bool allow_mouse_block)
{
BOOST_FOREACH(LLView* viewp, mChildList)
{
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if (!viewp->visibleEnabledAndContains(local_x, local_y))
{
continue;
}
if ((viewp->*method)( local_x, local_y, extra )
|| (allow_mouse_block && viewp->blockMouseEvent( local_x, local_y )))
{
viewp->logMouseEvent();
return viewp;
}
}
return NULL;
}
LLView* LLView::childrenHandleDragAndDrop(S32 x, S32 y, MASK mask,
BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
EAcceptance* accept,
std::string& tooltip_msg)
{
// default to not accepting drag and drop, will be overridden by handler
*accept = ACCEPT_NO;
BOOST_FOREACH(LLView* viewp, mChildList)
{
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if( !viewp->visibleEnabledAndContains(local_x, local_y))
{
continue;
}
// Differs from childrenHandleMouseEvent() simply in that this virtual
// method call diverges pretty radically from the usual (x, y, int).
if (viewp->handleDragAndDrop(local_x, local_y, mask, drop,
cargo_type,
cargo_data,
accept,
tooltip_msg)
|| viewp->blockMouseEvent(local_x, local_y))
{
return viewp;
}
}
return NULL;
}
LLView* LLView::childrenHandleHover(S32 x, S32 y, MASK mask)
{
BOOST_FOREACH(LLView* viewp, mChildList)
{
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if(!viewp->visibleEnabledAndContains(local_x, local_y))
{
continue;
}
// This call differentiates this method from childrenHandleMouseEvent().
LLUI::sWindow->setCursor(viewp->getHoverCursor());
if (viewp->handleHover(local_x, local_y, mask)
|| viewp->blockMouseEvent(local_x, local_y))
{
viewp->logMouseEvent();
return viewp;
}
}
return NULL;
}
BOOL LLView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
{
BOOL handled = FALSE;
@@ -847,53 +963,7 @@ BOOL LLView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EAcceptance* accept,
std::string& tooltip_msg)
{
// CRO this is an experiment to allow drag and drop into object inventory based on the DragAndDrop tool's permissions rather than the parent
BOOL handled = childrenHandleDragAndDrop( x, y, mask, drop,
cargo_type,
cargo_data,
accept,
tooltip_msg) != NULL;
if( !handled && blockMouseEvent(x, y) )
{
*accept = ACCEPT_NO;
handled = TRUE;
lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLView " << getName() << llendl;
}
return handled;
}
LLView* LLView::childrenHandleDragAndDrop(S32 x, S32 y, MASK mask,
BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
EAcceptance* accept,
std::string& tooltip_msg)
{
LLView* handled_view = FALSE;
// CRO this is an experiment to allow drag and drop into object inventory based on the DragAndDrop tool's permissions rather than the parent
if( getVisible() )
// if( getVisible() && getEnabled() )
{
BOOST_FOREACH(LLView* viewp, mChildList)
{
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if( viewp->pointInView(local_x, local_y) &&
viewp->getVisible() &&
viewp->getEnabled() &&
viewp->handleDragAndDrop(local_x, local_y, mask, drop,
cargo_type,
cargo_data,
accept,
tooltip_msg))
{
handled_view = viewp;
break;
}
}
}
return handled_view;
return childrenHandleDragAndDrop( x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg) != NULL;
}
void LLView::onMouseCaptureLost()
@@ -907,23 +977,12 @@ BOOL LLView::hasMouseCapture()
BOOL LLView::handleMouseUp(S32 x, S32 y, MASK mask)
{
BOOL handled = childrenHandleMouseUp( x, y, mask ) != NULL;
if( !handled && blockMouseEvent(x, y) )
{
handled = TRUE;
}
return handled;
return childrenHandleMouseUp( x, y, mask ) != NULL;
}
BOOL LLView::handleMouseDown(S32 x, S32 y, MASK mask)
{
LLView* handled_view = childrenHandleMouseDown( x, y, mask );
BOOL handled = (handled_view != NULL);
if( !handled && blockMouseEvent(x, y) )
{
handled = TRUE;
handled_view = this;
}
// HACK If we're editing UI, select the leaf view that ate the click.
if (sEditingUI && handled_view)
@@ -942,339 +1001,85 @@ BOOL LLView::handleMouseDown(S32 x, S32 y, MASK mask)
}
}
return handled;
return handled_view != NULL;
}
BOOL LLView::handleDoubleClick(S32 x, S32 y, MASK mask)
{
BOOL handled = childrenHandleDoubleClick( x, y, mask ) != NULL;
if( !handled && blockMouseEvent(x, y) )
{
handleMouseDown(x, y, mask);
handled = TRUE;
}
return handled;
return childrenHandleDoubleClick( x, y, mask ) != NULL;
}
BOOL LLView::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
BOOL handled = FALSE;
if( getVisible() && getEnabled() )
{
handled = childrenHandleScrollWheel( x, y, clicks ) != NULL;
if( !handled && blockMouseEvent(x, y) )
{
handled = TRUE;
}
}
return handled;
return childrenHandleScrollWheel( x, y, clicks ) != NULL;
}
BOOL LLView::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = childrenHandleRightMouseDown( x, y, mask ) != NULL;
if( !handled && blockMouseEvent(x, y) )
{
handled = TRUE;
}
return handled;
return childrenHandleRightMouseDown( x, y, mask ) != NULL;
}
BOOL LLView::handleRightMouseUp(S32 x, S32 y, MASK mask)
{
BOOL handled = childrenHandleRightMouseUp( x, y, mask ) != NULL;
if( !handled && blockMouseEvent(x, y) )
{
handled = TRUE;
}
return handled;
return childrenHandleRightMouseUp( x, y, mask ) != NULL;
}
BOOL LLView::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
{
LLView* handled_view = childrenHandleMiddleMouseDown( x, y, mask );
BOOL handled = (handled_view != NULL);
if( !handled && blockMouseEvent(x, y) )
{
handled = TRUE;
handled_view = this;
}
return handled;
return childrenHandleMiddleMouseDown( x, y, mask ) != NULL;
}
BOOL LLView::handleMiddleMouseUp(S32 x, S32 y, MASK mask)
{
BOOL handled = childrenHandleMiddleMouseUp( x, y, mask ) != NULL;
if( !handled && blockMouseEvent(x, y) )
{
handled = TRUE;
}
return handled;
return childrenHandleMiddleMouseUp( x, y, mask ) != NULL;
}
LLView* LLView::childrenHandleScrollWheel(S32 x, S32 y, S32 clicks)
{
LLView* handled_view = NULL;
if (getVisible() && getEnabled() )
{
BOOST_FOREACH(LLView* viewp, mChildList)
{
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if (viewp->pointInView(local_x, local_y)
&& viewp->getVisible()
&& viewp->getEnabled()
&& viewp->handleScrollWheel( local_x, local_y, clicks ))
{
if (sDebugMouseHandling)
{
sMouseHandlerMessage = std::string("->") + viewp->mName + sMouseHandlerMessage;
}
handled_view = viewp;
break;
}
}
}
return handled_view;
}
LLView* LLView::childrenHandleHover(S32 x, S32 y, MASK mask)
{
LLView* handled_view = NULL;
if (getVisible() && getEnabled() )
{
BOOST_FOREACH(LLView* viewp, mChildList)
{
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if(viewp->pointInView(local_x, local_y) &&
viewp->getVisible() &&
viewp->getEnabled() &&
viewp->handleHover(local_x, local_y, mask) )
{
if (sDebugMouseHandling)
{
sMouseHandlerMessage = std::string("->") + viewp->mName + sMouseHandlerMessage;
}
handled_view = viewp;
break;
}
}
}
return handled_view;
return childrenHandleMouseEvent(&LLView::handleScrollWheel, x, y, clicks, false);
}
// Called during downward traversal
LLView* LLView::childrenHandleKey(KEY key, MASK mask)
{
LLView* handled_view = NULL;
if ( getVisible() && getEnabled() )
{
BOOST_FOREACH(LLView* viewp, mChildList)
{
if (viewp->handleKey(key, mask, TRUE))
{
if (LLView::sDebugKeys)
{
llinfos << "Key handled by " << viewp->getName() << llendl;
}
handled_view = viewp;
break;
}
}
}
return handled_view;
return childrenHandleCharEvent("Key", &LLView::handleKey, key, mask);
}
// Called during downward traversal
LLView* LLView::childrenHandleUnicodeChar(llwchar uni_char)
{
LLView* handled_view = NULL;
if ( getVisible() && getEnabled() )
{
BOOST_FOREACH(LLView* viewp, mChildList)
{
if (viewp->handleUnicodeChar(uni_char, TRUE))
{
if (LLView::sDebugKeys)
{
llinfos << "Unicode character handled by " << viewp->getName() << llendl;
}
handled_view = viewp;
break;
}
}
}
return handled_view;
return childrenHandleCharEvent("Unicode character", &LLView::handleUnicodeCharWithDummyMask,
uni_char, MASK_NONE);
}
LLView* LLView::childrenHandleMouseDown(S32 x, S32 y, MASK mask)
{
LLView* handled_view = NULL;
BOOST_FOREACH(LLView* viewp, mChildList)
{
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if (viewp->pointInView(local_x, local_y) &&
viewp->getVisible() &&
viewp->getEnabled() &&
viewp->handleMouseDown( local_x, local_y, mask ))
{
if (sDebugMouseHandling)
{
sMouseHandlerMessage = std::string("->") + viewp->mName + sMouseHandlerMessage;
}
handled_view = viewp;
break;
}
}
return handled_view;
return childrenHandleMouseEvent(&LLView::handleMouseDown, x, y, mask);
}
LLView* LLView::childrenHandleRightMouseDown(S32 x, S32 y, MASK mask)
{
LLView* handled_view = NULL;
if (getVisible() && getEnabled() )
{
BOOST_FOREACH(LLView* viewp, mChildList)
{
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if (viewp->pointInView(local_x, local_y) &&
viewp->getVisible() &&
viewp->getEnabled() &&
viewp->handleRightMouseDown( local_x, local_y, mask ))
{
if (sDebugMouseHandling)
{
sMouseHandlerMessage = std::string("->") + viewp->mName + sMouseHandlerMessage;
}
handled_view = viewp;
break;
}
}
}
return handled_view;
return childrenHandleMouseEvent(&LLView::handleRightMouseDown, x, y, mask);
}
LLView* LLView::childrenHandleMiddleMouseDown(S32 x, S32 y, MASK mask)
{
LLView* handled_view = NULL;
if (getVisible() && getEnabled() )
{
BOOST_FOREACH(LLView* viewp, mChildList)
{
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if (viewp->pointInView(local_x, local_y) &&
viewp->getVisible() &&
viewp->getEnabled() &&
viewp->handleMiddleMouseDown( local_x, local_y, mask ))
{
if (sDebugMouseHandling)
{
sMouseHandlerMessage = std::string("->") + viewp->mName + sMouseHandlerMessage;
}
handled_view = viewp;
break;
}
}
}
return handled_view;
return childrenHandleMouseEvent(&LLView::handleMiddleMouseDown, x, y, mask);
}
LLView* LLView::childrenHandleDoubleClick(S32 x, S32 y, MASK mask)
{
LLView* handled_view = NULL;
if (getVisible() && getEnabled() )
{
BOOST_FOREACH(LLView* viewp, mChildList)
{
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if (viewp->pointInView(local_x, local_y) &&
viewp->getVisible() &&
viewp->getEnabled() &&
viewp->handleDoubleClick( local_x, local_y, mask ))
{
if (sDebugMouseHandling)
{
sMouseHandlerMessage = std::string("->") + viewp->mName + sMouseHandlerMessage;
}
handled_view = viewp;
break;
}
}
}
return handled_view;
return childrenHandleMouseEvent(&LLView::handleDoubleClick, x, y, mask);
}
LLView* LLView::childrenHandleMouseUp(S32 x, S32 y, MASK mask)
{
LLView* handled_view = NULL;
if( getVisible() && getEnabled() )
{
BOOST_FOREACH(LLView* viewp, mChildList)
{
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if (!viewp->pointInView(local_x, local_y))
continue;
if (!viewp->getVisible())
continue;
if (!viewp->getEnabled())
continue;
if (viewp->handleMouseUp( local_x, local_y, mask ))
{
if (sDebugMouseHandling)
{
sMouseHandlerMessage = std::string("->") + viewp->mName + sMouseHandlerMessage;
}
handled_view = viewp;
break;
}
}
}
return handled_view;
return childrenHandleMouseEvent(&LLView::handleMouseUp, x, y, mask);
}
LLView* LLView::childrenHandleRightMouseUp(S32 x, S32 y, MASK mask)
{
LLView* handled_view = NULL;
if( getVisible() && getEnabled() )
{
BOOST_FOREACH(LLView* viewp, mChildList)
{
S32 local_x = x - viewp->getRect().mLeft;
S32 local_y = y - viewp->getRect().mBottom;
if (viewp->pointInView(local_x, local_y) &&
viewp->getVisible() &&
viewp->getEnabled() &&
viewp->handleRightMouseUp( local_x, local_y, mask ))
{
if (sDebugMouseHandling)
{
sMouseHandlerMessage = std::string("->") + viewp->mName + sMouseHandlerMessage;
}
handled_view = viewp;
break;
}
}
}
return handled_view;
return childrenHandleMouseEvent(&LLView::handleRightMouseUp, x, y, mask);
}
LLView* LLView::childrenHandleMiddleMouseUp(S32 x, S32 y, MASK mask)
@@ -1732,14 +1537,14 @@ LLView* LLView::getChildView(const std::string& name, BOOL recurse, BOOL create_
BOOL LLView::parentPointInView(S32 x, S32 y, EHitTestType type) const
{
return (mUseBoundingRect && type == HIT_TEST_USE_BOUNDING_RECT)
return (getUseBoundingRect() && type == HIT_TEST_USE_BOUNDING_RECT)
? mBoundingRect.pointInRect( x, y )
: mRect.pointInRect( x, y );
}
BOOL LLView::pointInView(S32 x, S32 y, EHitTestType type) const
{
return (mUseBoundingRect && type == HIT_TEST_USE_BOUNDING_RECT)
return (getUseBoundingRect() && type == HIT_TEST_USE_BOUNDING_RECT)
? mBoundingRect.pointInRect( x + mRect.mLeft, y + mRect.mBottom )
: mRect.localPointInRect( x, y );
}

View File

@@ -279,6 +279,8 @@ public:
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);
@@ -590,6 +592,9 @@ 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* childrenHandleUnicodeChar(llwchar uni_char);
@@ -616,6 +621,21 @@ protected:
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;
@@ -664,6 +684,34 @@ private:
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.

View File

@@ -297,10 +297,6 @@
name="Wearable Edit" width="128">
<on_click filter="" function="Inventory.DoToSelected" userdata="edit" />
</menu_item_call>
<menu_item_call bottom_delta="-18" height="18" label="Wear" left="0" mouse_opaque="true"
name="Wearable And Object Wear" width="128">
<on_click filter="" function="Inventory.DoToSelected" userdata="wear" />
</menu_item_call>
<menu_item_call bottom_delta="-18" height="18" label="Take Off" left="0" mouse_opaque="true"
name="Take Off" width="128">
<on_click filter="" function="Inventory.DoToSelected" userdata="take_off" />

View File

@@ -15,24 +15,24 @@
<text text_color="0,0,0,1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
bottom="-17" drop_shadow_visible="true" follows="top|left"
font="SansSerifBold" h_pad="0" halign="left" height="16" left="4"
mouse_opaque="true" name="artist_label" v_pad="0" width="50">
mouse_opaque="false" name="artist_label" v_pad="0" width="50">
Artist:
</text>
<text text_color="0,0,0,1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
bottom="-17" drop_shadow_visible="true" follows="top|left|right"
font="SansSerifBold" h_pad="0" halign="left" height="16" left="50"
mouse_opaque="true" name="artist_text" v_pad="0" width="125">
mouse_opaque="false" name="artist_text" v_pad="0" width="125">
</text>
<text text_color="0,0,0,1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
bottom="-32" drop_shadow_visible="true" follows="top|left"
font="SansSerifBold" h_pad="0" halign="left" height="16" left="4"
mouse_opaque="true" name="title_label" v_pad="0" width="50">
mouse_opaque="false" name="title_label" v_pad="0" width="50">
Title:
</text>
<text text_color="0,0,0,1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
bottom="-32" drop_shadow_visible="true" follows="top|left|right"
font="SansSerifBold" h_pad="0" halign="left" height="16" left="50"
mouse_opaque="true" name="title_text" v_pad="0" width="125">
mouse_opaque="false" name="title_text" v_pad="0" width="125">
</text>
<string name="paused">