diff options
Diffstat (limited to 'indra')
28 files changed, 533 insertions, 189 deletions
| diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 98c9217306..ce25ee32b3 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -160,7 +160,7 @@ LLComboBox::LLComboBox(const LLComboBox::Params& p)  	createLineEditor(p); -	setTopLostCallback(boost::bind(&LLComboBox::hideList, this)); +	mTopLostSignalConnection = setTopLostCallback(boost::bind(&LLComboBox::hideList, this));  }  void LLComboBox::initFromParams(const LLComboBox::Params& p) @@ -187,6 +187,9 @@ BOOL LLComboBox::postBuild()  LLComboBox::~LLComboBox()  {  	// children automatically deleted, including mMenu, mButton + +	// explicitly disconect this signal, since base class destructor might fire top lost +	mTopLostSignalConnection.disconnect();  } @@ -612,16 +615,14 @@ void LLComboBox::showList()  	mList->setFocus(TRUE); -	// register ourselves as a "top" control -	// effectively putting us into a special draw layer -	// and not affecting the bounding rectangle calculation -	gFocusMgr.setTopCtrl(this); -  	// Show the list and push the button down  	mButton->setToggleState(TRUE);  	mList->setVisible(TRUE); +	LLUI::addPopup(this); +  	setUseBoundingRect(TRUE); +//	updateBoundingRect();  }  void LLComboBox::hideList() @@ -644,10 +645,8 @@ void LLComboBox::hideList()  		mList->mouseOverHighlightNthItem(-1);  		setUseBoundingRect(FALSE); -		if( gFocusMgr.getTopCtrl() == this ) -		{ -			gFocusMgr.setTopCtrl(NULL); -		} +		LLUI::removePopup(this); +//		updateBoundingRect();  	}  } diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index 3cc2a8f5d1..c694724248 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -231,6 +231,7 @@ private:  	commit_callback_t	mPrearrangeCallback;  	commit_callback_t	mTextEntryCallback;  	commit_callback_t	mSelectionCallback; +        boost::signals2::connection mTopLostSignalConnection;  };  // A combo box with icons for the list of items. diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index e91d753a39..4cb336f7ea 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -527,10 +527,7 @@ void LLFloater::setVisible( BOOL visible )  	if( !visible )  	{ -		if( gFocusMgr.childIsTopCtrl( this ) ) -		{ -			gFocusMgr.setTopCtrl(NULL); -		} +		LLUI::removePopup(this);  		if( gFocusMgr.childHasMouseCapture( this ) )  		{ @@ -704,10 +701,7 @@ void LLFloater::reshape(S32 width, S32 height, BOOL called_from_parent)  void LLFloater::releaseFocus()  { -	if( gFocusMgr.childIsTopCtrl( this ) ) -	{ -		gFocusMgr.setTopCtrl(NULL); -	} +	LLUI::removePopup(this);  	setFocus(FALSE); @@ -1360,7 +1354,7 @@ void LLFloater::bringToFront( S32 x, S32 y )  // virtual  void LLFloater::setVisibleAndFrontmost(BOOL take_focus)  { -	gFocusMgr.setTopCtrl(NULL); +	LLUI::clearPopups();  	setVisible(TRUE);  	setFrontmost(take_focus);  } @@ -2508,10 +2502,7 @@ void LLFloaterView::syncFloaterTabOrder()  	if (modal_dialog)  	{  		// If we have a visible modal dialog, make sure that it has focus -		if( gFocusMgr.getTopCtrl() != modal_dialog ) -		{ -			gFocusMgr.setTopCtrl( modal_dialog ); -		} +		LLUI::addPopup(modal_dialog);  		if( !gFocusMgr.childHasKeyboardFocus( modal_dialog ) )  		{ diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp index 35fbc7b0a8..b3af258456 100644 --- a/indra/llui/llfocusmgr.cpp +++ b/indra/llui/llfocusmgr.cpp @@ -38,8 +38,6 @@  const F32 FOCUS_FADE_TIME = 0.3f; -// NOTE: the LLFocusableElement implementation has been moved here from lluictrl.cpp. -  LLFocusableElement::LLFocusableElement()  :	mFocusLostCallback(NULL),  	mFocusReceivedCallback(NULL), @@ -124,8 +122,7 @@ boost::signals2::connection	LLFocusableElement::setTopLostCallback(const focus_s  LLFocusMgr gFocusMgr;  LLFocusMgr::LLFocusMgr() -	: -	mLockedView( NULL ), +:	mLockedView( NULL ),  	mMouseCaptor( NULL ),  	mKeyboardFocus( NULL ),  	mLastKeyboardFocus( NULL ), @@ -133,16 +130,11 @@ LLFocusMgr::LLFocusMgr()  	mKeystrokesOnly(FALSE),  	mTopCtrl( NULL ),  	mAppHasFocus(TRUE)   // Macs don't seem to notify us that we've gotten focus, so default to true -	#ifdef _DEBUG -		, mMouseCaptorName("none") -		, mKeyboardFocusName("none") -		, mTopCtrlName("none") -	#endif  {  } -void LLFocusMgr::releaseFocusIfNeeded( const LLView* view ) +void LLFocusMgr::releaseFocusIfNeeded( LLView* view )  {  	if( childHasMouseCapture( view ) )  	{ @@ -162,10 +154,7 @@ void LLFocusMgr::releaseFocusIfNeeded( const LLView* view )  		}  	} -	if( childIsTopCtrl( view ) ) -	{ -		setTopCtrl( NULL ); -	} +	LLUI::removePopup(view);  } @@ -248,11 +237,6 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL  			return;  		} -		#ifdef _DEBUG -			LLUICtrl* focus_ctrl = dynamic_cast<LLUICtrl*>(new_focus); -			mKeyboardFocusName = focus_ctrl ? focus_ctrl->getName() : std::string("none"); -		#endif -  		// If we've got a default keyboard focus, and the caller is  		// releasing keyboard focus, move to the default.  		if (mDefaultKeyboardFocus != NULL && mKeyboardFocus == NULL) @@ -334,20 +318,12 @@ void LLFocusMgr::removeKeyboardFocusWithoutCallback( const LLFocusableElement* f  	if( mKeyboardFocus == focus )  	{  		mKeyboardFocus = NULL; -		#ifdef _DEBUG -			mKeyboardFocusName = std::string("none"); -		#endif  	}  }  void LLFocusMgr::setMouseCapture( LLMouseHandler* new_captor )  { -	//if (mFocusLocked) -	//{ -	//	return; -	//} -  	if( new_captor != mMouseCaptor )  	{  		LLMouseHandler* old_captor = mMouseCaptor; @@ -370,24 +346,14 @@ void LLFocusMgr::setMouseCapture( LLMouseHandler* new_captor )  			old_captor->onMouseCaptureLost();  		} -		#ifdef _DEBUG -			mMouseCaptorName = new_captor ? new_captor->getName() : std::string("none"); -		#endif  	}  }  void LLFocusMgr::removeMouseCaptureWithoutCallback( const LLMouseHandler* captor )  { -	//if (mFocusLocked) -	//{ -	//	return; -	//}  	if( mMouseCaptor == captor )  	{  		mMouseCaptor = NULL; -		#ifdef _DEBUG -			mMouseCaptorName = std::string("none"); -		#endif  	}  } @@ -416,10 +382,6 @@ void LLFocusMgr::setTopCtrl( LLUICtrl* new_top  )  	{  		mTopCtrl = new_top; -		#ifdef _DEBUG -			mTopCtrlName = new_top ? new_top->getName() : std::string("none"); -		#endif -  		if (old_top)  		{  			old_top->onTopLost(); @@ -432,9 +394,6 @@ void LLFocusMgr::removeTopCtrlWithoutCallback( const LLUICtrl* top_view )  	if( mTopCtrl == top_view )  	{  		mTopCtrl = NULL; -		#ifdef _DEBUG -			mTopCtrlName = std::string("none"); -		#endif  	}  } @@ -478,9 +437,9 @@ void LLFocusMgr::setAppHasFocus(BOOL focus)  	}  	// release focus from "top ctrl"s, which generally hides them -	if (!focus && mTopCtrl) +	if (!focus)  	{ -		setTopCtrl(NULL); +		LLUI::clearPopups();  	}  	mAppHasFocus = focus;   } diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h index 83ecd1d301..86d3ccf111 100644 --- a/indra/llui/llfocusmgr.h +++ b/indra/llui/llfocusmgr.h @@ -65,10 +65,10 @@ public:  	virtual BOOL	handleKey(KEY key, MASK mask, BOOL called_from_parent);  	virtual BOOL	handleUnicodeChar(llwchar uni_char, BOOL called_from_parent); +	virtual void	onTopLost();	// called when registered as top ctrl and user clicks elsewhere  protected:	  	virtual void	onFocusReceived();  	virtual void	onFocusLost(); -	virtual void	onTopLost();	// called when registered as top ctrl and user clicks elsewhere  	focus_signal_t*  mFocusLostCallback;  	focus_signal_t*  mFocusReceivedCallback;  	focus_signal_t*  mFocusChangedCallback; @@ -119,7 +119,7 @@ public:  	BOOL			childIsTopCtrl( const LLView* parent ) const;  	// All Three -	void			releaseFocusIfNeeded( const LLView* top_view ); +	void			releaseFocusIfNeeded( LLView* top_view );  	void			lockFocus();  	void			unlockFocus();  	BOOL			focusLocked() const { return mLockedView != NULL; } @@ -149,12 +149,6 @@ private:  	typedef std::map<LLHandle<LLView>, LLHandle<LLView> > focus_history_map_t;  	focus_history_map_t mFocusHistory; - -	#ifdef _DEBUG -		std::string		mMouseCaptorName; -		std::string		mKeyboardFocusName; -		std::string		mTopCtrlName; -	#endif  };  extern LLFocusMgr gFocusMgr; diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h index 899f6b9326..8ade327044 100644 --- a/indra/llui/llhandle.h +++ b/indra/llui/llhandle.h @@ -67,6 +67,13 @@ public:  		return *this;   	} +	template<typename Subclass> +	LLHandle<T>& operator =(const LLHandle<Subclass>& other)   +	{  +		mTombStone = other.mTombStone; +		return *this;  +	} +  	bool isDead() const   	{   		return mTombStone->getTarget() == NULL;  diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp index 387af05935..6cff68c20b 100644 --- a/indra/llui/llmodaldialog.cpp +++ b/indra/llui/llmodaldialog.cpp @@ -111,7 +111,7 @@ void LLModalDialog::onOpen(const LLSD& key)  		// This is a modal dialog.  It sucks up all mouse and keyboard operations.  		gFocusMgr.setMouseCapture( this ); -		gFocusMgr.setTopCtrl( this ); +		LLUI::addPopup(this);  		setFocus(TRUE);  		sModalStack.push_front( this ); @@ -153,7 +153,7 @@ void LLModalDialog::setVisible( BOOL visible )  			gFocusMgr.setMouseCapture( this );  			// The dialog view is a root view -			gFocusMgr.setTopCtrl( this ); +			LLUI::addPopup(this);  			setFocus( TRUE );  		}  		else @@ -291,7 +291,7 @@ void LLModalDialog::onAppFocusGained()  		// This is a modal dialog.  It sucks up all mouse and keyboard operations.  		gFocusMgr.setMouseCapture( instance );  		instance->setFocus(TRUE); -		gFocusMgr.setTopCtrl( instance ); +		LLUI::addPopup(instance);  		instance->centerOnScreen();  	} diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index b348ec2d29..5121ef5351 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -86,6 +86,9 @@ std::list<std::string> gUntranslated;  /*static*/ LLHelp*			LLUI::sHelpImpl = NULL;  /*static*/ std::vector<std::string> LLUI::sXUIPaths;  /*static*/ LLFrameTimer		LLUI::sMouseIdleTimer; +/*static*/ LLUI::add_popup_t	LLUI::sAddPopupFunc; +/*static*/ LLUI::remove_popup_t	LLUI::sRemovePopupFunc; +/*static*/ LLUI::clear_popups_t	LLUI::sClearPopupsFunc;  // register filtereditor here  static LLDefaultChildRegistry::Register<LLFilterEditor> register_filter_editor("filter_editor"); @@ -1607,6 +1610,13 @@ void LLUI::cleanupClass()  	sImageProvider->cleanUp();  } +void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup,  const clear_popups_t& clear_popups) +{ +	sAddPopupFunc = add_popup; +	sRemovePopupFunc = remove_popup; +	sClearPopupsFunc = clear_popups; +} +  //static  void LLUI::dirtyRect(LLRect rect)  { @@ -1877,6 +1887,34 @@ LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname)  	return *sSettingGroups["config"]; // default group  } +//static  +void LLUI::addPopup(LLView* viewp) +{ +	if (sAddPopupFunc) +	{ +		sAddPopupFunc(viewp); +	} +} + +//static  +void LLUI::removePopup(LLView* viewp) +{ +	if (sRemovePopupFunc) +	{ +		sRemovePopupFunc(viewp); +	} +} + +//static +void LLUI::clearPopups() +{ +	if (sClearPopupsFunc) +	{ +		sClearPopupsFunc(); +	} +} + +  //static  // spawn_x and spawn_y are top left corner of view in screen GL coordinates  void LLUI::positionViewNearMouse(LLView* view, S32 spawn_x, S32 spawn_y) diff --git a/indra/llui/llui.h b/indra/llui/llui.h index af8d4ea03b..30f3623ded 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -160,12 +160,17 @@ public:  	// Methods  	//  	typedef std::map<std::string, LLControlGroup*> settings_map_t; +	typedef boost::function<void(LLView*)> add_popup_t; +	typedef boost::function<void(LLView*)> remove_popup_t; +	typedef boost::function<void(void)> clear_popups_t; +  	static void initClass(const settings_map_t& settings,  						  LLImageProviderInterface* image_provider,  						  LLUIAudioCallback audio_callback = NULL,  						  const LLVector2 *scale_factor = NULL,  						  const std::string& language = LLStringUtil::null);  	static void cleanupClass(); +	static void setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t&, const clear_popups_t& );  	static void pushMatrix();  	static void popMatrix(); @@ -208,6 +213,10 @@ public:  	static void resetMouseIdleTimer() { sMouseIdleTimer.reset(); }  	static LLWindow* getWindow() { return sWindow; } +	static void addPopup(LLView*); +	static void removePopup(LLView*); +	static void clearPopups(); +  	// Ensures view does not overlap mouse cursor, but is inside  	// the view's parent rectangle.  Used for tooltips, inspectors.  	// Optionally override the view's default X/Y, which are relative to the @@ -227,6 +236,9 @@ private:  	static LLImageProviderInterface* sImageProvider;  	static std::vector<std::string> sXUIPaths;  	static LLFrameTimer		sMouseIdleTimer; +	static add_popup_t		sAddPopupFunc; +	static remove_popup_t	sRemovePopupFunc; +	static clear_popups_t	sClearPopupsFunc;  }; diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 63e627ceb5..db2c460eec 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -592,11 +592,6 @@ void LLView::setVisible(BOOL visible)  {  	if ( mVisible != visible )  	{ -		if( !visible && (gFocusMgr.getTopCtrl() == this) ) -		{ -			gFocusMgr.setTopCtrl( NULL ); -		} -  		mVisible = visible;  		// notify children of visibility change if root, or part of visible hierarchy diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 14eb75e457..8ad3b2085d 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -347,6 +347,7 @@ set(viewer_SOURCE_FILES      llpatchvertexarray.cpp      llplacesinventorybridge.cpp      llplacesinventorypanel.cpp +    llpopupview.cpp      llpolymesh.cpp      llpolymorph.cpp      llpreview.cpp @@ -844,6 +845,7 @@ set(viewer_HEADER_FILES      llplacesinventorypanel.h      llpolymesh.h      llpolymorph.h +    llpopupview.h      llpreview.h      llpreviewanim.h      llpreviewgesture.h diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index ccd58e26fe..36faeb100f 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -703,9 +703,9 @@ bool LLAppViewer::init()  	settings_map["account"] = &gSavedPerAccountSettings;  	LLUI::initClass(settings_map, -					LLUIImageList::getInstance(), -					ui_audio_callback, -					&LLUI::sGLScaleFactor); +		LLUIImageList::getInstance(), +		ui_audio_callback, +		&LLUI::sGLScaleFactor);  	// Setup paths and LLTrans after LLUI::initClass has been called  	LLUI::setupPaths(); diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp index 3818ee6f78..362010d65a 100644 --- a/indra/newview/llexpandabletextbox.cpp +++ b/indra/newview/llexpandabletextbox.cpp @@ -35,6 +35,7 @@  #include "llscrollcontainer.h"  #include "llwindow.h" +#include "llviewerwindow.h"  static LLDefaultChildRegistry::Register<LLExpandableTextBox> t1("expandable_text"); @@ -382,7 +383,7 @@ void LLExpandableTextBox::expandTextBox()  	setFocus(TRUE);  	// this lets us receive top_lost event(needed to collapse text box)  	// it also draws text box above all other ui elements -	gFocusMgr.setTopCtrl(this); +	gViewerWindow->addPopup(this);  	mExpanded = true;  } @@ -401,10 +402,7 @@ void LLExpandableTextBox::collapseTextBox()  	updateTextBoxRect(); -	if(gFocusMgr.getTopCtrl() == this) -	{ -		gFocusMgr.setTopCtrl(NULL); -	} +	gViewerWindow->removePopup(this);  }  void LLExpandableTextBox::onFocusLost() diff --git a/indra/newview/llexpandabletextbox.h b/indra/newview/llexpandabletextbox.h index 58316ddb98..9d4a8aef76 100644 --- a/indra/newview/llexpandabletextbox.h +++ b/indra/newview/llexpandabletextbox.h @@ -144,6 +144,7 @@ public:  	 */  	/*virtual*/ void onTopLost(); +  	/**  	 * Draws text box, collapses text box if its expanded and its parent's position changed  	 */ diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index f7fd7bb472..cc807c2370 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -285,10 +285,7 @@ LLFolderView::~LLFolderView( void )  	LLView::deleteViewByHandle(mPopupMenuHandle); -	if(mRenamer == gFocusMgr.getTopCtrl()) -	{ -		gFocusMgr.setTopCtrl(NULL); -	} +	gViewerWindow->removePopup(mRenamer);  	mAutoOpenItems.removeAllNodes();  	clearSelection(); @@ -972,7 +969,7 @@ void LLFolderView::finishRenamingItem( void )  		mRenameItem->rename( mRenamer->getText() );  	} -	gFocusMgr.setTopCtrl( NULL );	 +	gViewerWindow->removePopup(mRenamer);  	if( mRenameItem )  	{ @@ -989,7 +986,7 @@ void LLFolderView::closeRenamer( void )  	// will commit current name (which could be same as original name)  	mRenamer->setFocus( FALSE );  	mRenamer->setVisible( FALSE ); -	gFocusMgr.setTopCtrl( NULL ); +	gViewerWindow->removePopup(mRenamer);  	if( mRenameItem )  	{ @@ -1421,7 +1418,7 @@ void LLFolderView::startRenamingSelectedItem( void )  		mRenamer->setFocus( TRUE );  		mRenamer->setTopLostCallback(boost::bind(onRenamerLost, _1));  		mRenamer->setFocusLostCallback(boost::bind(onRenamerLost, _1)); -		gFocusMgr.setTopCtrl( mRenamer ); +		gViewerWindow->addPopup(mRenamer);  	}  } @@ -1902,7 +1899,7 @@ void LLFolderView::deleteAllChildren()  {  	if(mRenamer == gFocusMgr.getTopCtrl())  	{ -		gFocusMgr.setTopCtrl(NULL); +		gViewerWindow->removePopup(mRenamer);  	}  	LLView::deleteViewByHandle(mPopupMenuHandle);  	mPopupMenuHandle = LLHandle<LLView>(); diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp index a73c25a979..4f2d6374ca 100644 --- a/indra/newview/llpanelnearbymedia.cpp +++ b/indra/newview/llpanelnearbymedia.cpp @@ -82,6 +82,8 @@ LLPanelNearByMedia::LLPanelNearByMedia()  	  mParcelMediaItem(NULL),  	  mParcelAudioItem(NULL)  { +	mHoverTimer.stop(); +  	mParcelAudioAutoStart = gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&  							gSavedSettings.getBOOL("MediaTentativeAutoPlay"); @@ -188,33 +190,25 @@ void LLPanelNearByMedia::onMouseLeave(S32 x, S32 y, MASK mask)  }  /*virtual*/  +void LLPanelNearByMedia::onTopLost() +{ +	setVisible(FALSE); +} + + +/*virtual*/   void LLPanelNearByMedia::handleVisibilityChange ( BOOL new_visibility )  {  	if (new_visibility)	  	{  		mHoverTimer.start(); // timer will be stopped when mouse hovers over panel -		//gFocusMgr.setTopCtrl(this);  	}  	else  	{  		mHoverTimer.stop(); -		//if (gFocusMgr.getTopCtrl() == this) -		//{ -		//	gFocusMgr.setTopCtrl(NULL); -		//}  	}  } -/*virtual*/  -void LLPanelNearByMedia::onTopLost () -{ -	//LLUICtrl* new_top = gFocusMgr.getTopCtrl(); -	//if (!new_top || !new_top->hasAncestor(this)) -	//{ -	//	setVisible(FALSE); -	//} -} -  /*virtual*/  void LLPanelNearByMedia::reshape(S32 width, S32 height, BOOL called_from_parent)  { @@ -234,13 +228,6 @@ const F32 AUTO_CLOSE_FADE_TIME_END = 5.0f;  /*virtual*/  void LLPanelNearByMedia::draw()  { -	//LLUICtrl* new_top = gFocusMgr.getTopCtrl(); -	//if (new_top != this) -	//{ -	//	// reassert top ctrl -	//	gFocusMgr.setTopCtrl(this); -	//} -  	// keep bottom of panel on screen  	LLRect screen_rect = calcScreenRect();  	if (screen_rect.mBottom < 0) diff --git a/indra/newview/llpanelnearbymedia.h b/indra/newview/llpanelnearbymedia.h index 4f864519f5..af4659365f 100644 --- a/indra/newview/llpanelnearbymedia.h +++ b/indra/newview/llpanelnearbymedia.h @@ -53,8 +53,8 @@ public:  	/*virtual*/ void draw();  	/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);  	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); +	/*virtual*/ void onTopLost();  	/*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); -	/*virtual*/ void onTopLost ();  	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent);  	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); diff --git a/indra/newview/llpanelvolumepulldown.cpp b/indra/newview/llpanelvolumepulldown.cpp index 559997254e..ae52bd3703 100644 --- a/indra/newview/llpanelvolumepulldown.cpp +++ b/indra/newview/llpanelvolumepulldown.cpp @@ -56,6 +56,8 @@  // Default constructor  LLPanelVolumePulldown::LLPanelVolumePulldown()  { +	mHoverTimer.stop(); +      mCommitCallbackRegistrar.add("Vol.setControlFalse", boost::bind(&LLPanelVolumePulldown::setControlFalse, this, _2));  	mCommitCallbackRegistrar.add("Vol.GoAudioPrefs", boost::bind(&LLPanelVolumePulldown::onAdvancedButtonClick, this, _2));  	LLUICtrlFactory::instance().buildPanel(this, "panel_volume_pulldown.xml"); @@ -77,6 +79,11 @@ void LLPanelVolumePulldown::onMouseEnter(S32 x, S32 y, MASK mask)  	LLPanel::onMouseEnter(x,y,mask);  } +/*virtual*/ +void LLPanelVolumePulldown::onTopLost() +{ +	setVisible(FALSE); +}  /*virtual*/  void LLPanelVolumePulldown::onMouseLeave(S32 x, S32 y, MASK mask) @@ -95,13 +102,8 @@ void LLPanelVolumePulldown::handleVisibilityChange ( BOOL new_visibility )  	else  	{  		mHoverTimer.stop(); -	} -} -/*virtual*/  -void LLPanelVolumePulldown::onTopLost() -{ -	setVisible(FALSE); +	}  }  void LLPanelVolumePulldown::onAdvancedButtonClick(const LLSD& user_data) diff --git a/indra/newview/llpanelvolumepulldown.h b/indra/newview/llpanelvolumepulldown.h index 9f20caa1a8..7fb025f329 100644 --- a/indra/newview/llpanelvolumepulldown.h +++ b/indra/newview/llpanelvolumepulldown.h @@ -47,8 +47,8 @@ class LLPanelVolumePulldown : public LLPanel  	/*virtual*/ void draw();  	/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);  	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); -	/*virtual*/ void handleVisibilityChange ( BOOL new_visibility );  	/*virtual*/ void onTopLost(); +	/*virtual*/ void handleVisibilityChange ( BOOL new_visibility );  	/*virtual*/ BOOL postBuild();   private: diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp new file mode 100644 index 0000000000..590a45c96c --- /dev/null +++ b/indra/newview/llpopupview.cpp @@ -0,0 +1,242 @@ +/**  + * @file llpopupview.cpp + * @brief Holds transient popups + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + *  + * Copyright (c) 2001-2010, 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$ + */ +#include "llviewerprecompiledheaders.h" + +#include "llpopupview.h" + +static LLRegisterPanelClassWrapper<LLPopupView> r("popup_holder"); + +bool view_visible_and_enabled(LLView* viewp) +{ +	return viewp->getVisible() && viewp->getEnabled(); +} + +bool view_visible(LLView* viewp) +{ +	return viewp->getVisible(); +} + + +LLPopupView::LLPopupView() +{ +	// register ourself as handler of UI popups +	LLUI::setPopupFuncs(boost::bind(&LLPopupView::addPopup, this, _1), boost::bind(&LLPopupView::removePopup, this, _1), boost::bind(&LLPopupView::clearPopups, this)); +} + +LLPopupView::~LLPopupView() +{ +	// set empty callback function so we can't handle popups anymore +	LLUI::setPopupFuncs(LLUI::add_popup_t(), LLUI::remove_popup_t(), LLUI::clear_popups_t()); +} + +void LLPopupView::draw() +{ +	S32 screen_x, screen_y; + +	// remove dead popups +	for (popup_list_t::iterator popup_it = mPopups.begin(); +		popup_it != mPopups.end();) +	{ +		if (!popup_it->get()) +		{ +			mPopups.erase(popup_it++); +		} +		else +		{ +			popup_it++; +		} +	} + +	// draw in reverse order (most recent is on top) +	for (popup_list_t::reverse_iterator popup_it = mPopups.rbegin(); +		popup_it != mPopups.rend();) +	{ +		LLView* popup = popup_it->get(); + +		if (popup->getVisible()) +		{ +			popup->localPointToScreen(0, 0, &screen_x, &screen_y); + +			LLUI::pushMatrix(); +			{ +				LLUI::translate( (F32) screen_x, (F32) screen_y, 0.f); +				popup->draw(); +			} +			LLUI::popMatrix(); +		} +		++popup_it; +	} + +	LLPanel::draw(); +} + +BOOL LLPopupView::handleMouseEvent(boost::function<BOOL(LLView*, S32, S32)> func,  +								   boost::function<bool(LLView*)> predicate,  +								   S32 x, S32 y, +								   bool close_popups) +{ +	for (popup_list_t::iterator popup_it = mPopups.begin(); +		popup_it != mPopups.end();) +	{ +		LLView* popup = popup_it->get(); +		if (!popup  +			|| !predicate(popup)) +		{ +			++popup_it; +			continue; +		} + +		S32 popup_x, popup_y; +		if (localPointToOtherView(x, y, &popup_x, &popup_y, popup)  +			&& popup->pointInView(popup_x, popup_y)) +		{ +			if (func(popup, popup_x, popup_y)) +			{ +				return TRUE; +			} +		} + +		if (close_popups) +		{ +			popup_list_t::iterator cur_popup_it = popup_it++; +			mPopups.erase(cur_popup_it); +			popup->onTopLost(); +		} +		else +		{ +			++popup_it; +		} +	} + +	return FALSE; +} + + +BOOL LLPopupView::handleMouseDown(S32 x, S32 y, MASK mask) +{ +	if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true)) +	{ +		return FALSE; +	} +	return TRUE; +} + +BOOL LLPopupView::handleMouseUp(S32 x, S32 y, MASK mask) +{ +	return handleMouseEvent(boost::bind(&LLMouseHandler::handleMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y, false); +} + +BOOL LLPopupView::handleMiddleMouseDown(S32 x, S32 y, MASK mask) +{ +	if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleMiddleMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true)) +	{ +		return FALSE; +	} +	return TRUE; +} + +BOOL LLPopupView::handleMiddleMouseUp(S32 x, S32 y, MASK mask) +{ +	return handleMouseEvent(boost::bind(&LLMouseHandler::handleMiddleMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y, false); +} + +BOOL LLPopupView::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ +	if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleRightMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true)) +	{ +		return FALSE; +	} +	return TRUE; +} + +BOOL LLPopupView::handleRightMouseUp(S32 x, S32 y, MASK mask) +{ +	return handleMouseEvent(boost::bind(&LLMouseHandler::handleRightMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y, false); +} + +BOOL LLPopupView::handleDoubleClick(S32 x, S32 y, MASK mask) +{ +	return handleMouseEvent(boost::bind(&LLMouseHandler::handleDoubleClick, _1, _2, _3, mask), view_visible_and_enabled, x, y, false); +} + +BOOL LLPopupView::handleHover(S32 x, S32 y, MASK mask) +{ +	return handleMouseEvent(boost::bind(&LLMouseHandler::handleHover, _1, _2, _3, mask), view_visible_and_enabled, x, y, false); +} + +BOOL LLPopupView::handleScrollWheel(S32 x, S32 y, S32 clicks) +{ +	return handleMouseEvent(boost::bind(&LLMouseHandler::handleScrollWheel, _1, _2, _3, clicks), view_visible_and_enabled, x, y, false); +} + +BOOL LLPopupView::handleToolTip(S32 x, S32 y, MASK mask) +{ +	return handleMouseEvent(boost::bind(&LLMouseHandler::handleToolTip, _1, _2, _3, mask), view_visible, x, y, false); +} + +void LLPopupView::addPopup(LLView* popup) +{ +	if (popup) +	{ +		mPopups.erase(std::find(mPopups.begin(), mPopups.end(), popup->getHandle())); +		mPopups.push_front(popup->getHandle()); +	} +} + +void LLPopupView::removePopup(LLView* popup) +{ +	if (popup) +	{ +		if (gFocusMgr.childHasKeyboardFocus(popup)) +		{ +			gFocusMgr.setKeyboardFocus(NULL); +		} +		mPopups.erase(std::find(mPopups.begin(), mPopups.end(), popup->getHandle())); +		popup->onTopLost(); +	} +} + +void LLPopupView::clearPopups() +{ +	for (popup_list_t::iterator popup_it = mPopups.begin(); +		popup_it != mPopups.end();) +	{ +		LLView* popup = popup_it->get(); + +		popup_list_t::iterator cur_popup_it = popup_it; +		++popup_it; + +		mPopups.erase(cur_popup_it); +		popup->onTopLost(); +	} +} + diff --git a/indra/newview/llpopupview.h b/indra/newview/llpopupview.h new file mode 100644 index 0000000000..1ec61d5450 --- /dev/null +++ b/indra/newview/llpopupview.h @@ -0,0 +1,67 @@ +/**  + * @file llpopupview.h + * @brief Holds transient popups + * + * $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_LLPOPUPVIEW_H +#define LL_LLPOPUPVIEW_H + +#include "llpanel.h" + +class LLPopupView : public LLPanel +{ +public: +	LLPopupView(); +	~LLPopupView(); + +	/*virtual*/ void draw(); +	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); +	/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); +	/*virtual*/ BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask); +	/*virtual*/ BOOL handleMiddleMouseUp(S32 x, S32 y, MASK mask); +	/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); +	/*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); +	/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); +	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); +	/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); +	/*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask); + +	void addPopup(LLView* popup); +	void removePopup(LLView* popup); +	void clearPopups(); + +	typedef std::list<LLHandle<LLView> > popup_list_t; +	popup_list_t getCurrentPopups() { return mPopups; } + +private: +	BOOL handleMouseEvent(boost::function<BOOL(LLView*, S32, S32)>, boost::function<bool(LLView*)>, S32 x, S32 y, bool close_popups); +	popup_list_t mPopups; +}; +#endif //LL_LLROOTVIEW_H diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index 0476e785a5..120b584cd9 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -128,11 +128,13 @@ void LLProgressView::setVisible(BOOL visible)  {  	if (getVisible() && !visible)  	{ +  		mFadeTimer.start();  	}  	else if (!getVisible() && visible)  	{ -		gFocusMgr.setTopCtrl(this); +		gViewerWindow->addPopup(this); +  		setFocus(TRUE);  		mFadeTimer.stop();  		mProgressTimer.start(); @@ -187,6 +189,8 @@ void LLProgressView::draw()  			// Fade is complete, release focus  			gFocusMgr.releaseFocusIfNeeded( this );  			LLPanel::setVisible(FALSE); +			gViewerWindow->removePopup(this); +  			gStartTexture = NULL;  		}  		return; diff --git a/indra/newview/llsplitbutton.cpp b/indra/newview/llsplitbutton.cpp index ffd9bc7624..e5323db466 100644 --- a/indra/newview/llsplitbutton.cpp +++ b/indra/newview/llsplitbutton.cpp @@ -165,7 +165,7 @@ void LLSplitButton::showButtons()  	// register ourselves as a "top" control  	// effectively putting us into a special draw layer -	gFocusMgr.setTopCtrl(this); +	gViewerWindow->addPopup(this);  	mItemsPanel->setFocus(TRUE); @@ -182,10 +182,7 @@ void LLSplitButton::hideButtons()  	mArrowBtn->setToggleState(FALSE);  	setUseBoundingRect(FALSE); -	if(gFocusMgr.getTopCtrl() == this) -	{ -		gFocusMgr.setTopCtrl(NULL); -	} +	gViewerWindow->removePopup(this);  } diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 9fb496c214..9206b4a43a 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -239,20 +239,16 @@ BOOL LLStatusBar::postBuild()  	childSetActionTextbox("stat_btn", onClickStatGraph); -	LLView* popup_holder = gViewerWindow->getRootView()->getChildView("popup_holder"); -  	mPanelVolumePulldown = new LLPanelVolumePulldown(); -	popup_holder->addChild(mPanelVolumePulldown); +	addChild(mPanelVolumePulldown); +	mPanelVolumePulldown->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT); +	mPanelVolumePulldown->setVisible(FALSE);  	mPanelNearByMedia = new LLPanelNearByMedia(); -	popup_holder->addChild(mPanelNearByMedia); -	gViewerWindow->getRootView()->addMouseDownCallback(boost::bind(&LLStatusBar::onClickScreen, this, _1, _2)); +	addChild(mPanelNearByMedia);  	mPanelNearByMedia->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);  	mPanelNearByMedia->setVisible(FALSE); -	mPanelVolumePulldown->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT); -	mPanelVolumePulldown->setVisible(FALSE); -  	return TRUE;  } @@ -528,11 +524,11 @@ static void onClickScriptDebug(void*)  void LLStatusBar::onMouseEnterVolume()  {  	LLButton* volbtn =  getChild<LLButton>( "volume_btn" ); -	LLRect vol_btn_screen_rect = volbtn->calcScreenRect(); +	LLRect vol_btn_rect = volbtn->getRect();  	LLRect volume_pulldown_rect = mPanelVolumePulldown->getRect(); -	volume_pulldown_rect.setLeftTopAndSize(vol_btn_screen_rect.mLeft - -	     (volume_pulldown_rect.getWidth() - vol_btn_screen_rect.getWidth())/2, -			       vol_btn_screen_rect.mBottom, +	volume_pulldown_rect.setLeftTopAndSize(vol_btn_rect.mLeft - +	     (volume_pulldown_rect.getWidth() - vol_btn_rect.getWidth())/2, +			       vol_btn_rect.mBottom,  			       volume_pulldown_rect.getWidth(),  			       volume_pulldown_rect.getHeight()); @@ -540,8 +536,10 @@ void LLStatusBar::onMouseEnterVolume()  	// show the master volume pull-down -	mPanelVolumePulldown->setVisible(TRUE); +	LLUI::clearPopups(); +	LLUI::addPopup(mPanelVolumePulldown);  	mPanelNearByMedia->setVisible(FALSE); +	mPanelVolumePulldown->setVisible(TRUE);  }  void LLStatusBar::onMouseEnterNearbyMedia() @@ -549,7 +547,7 @@ void LLStatusBar::onMouseEnterNearbyMedia()  	LLView* popup_holder = gViewerWindow->getRootView()->getChildView("popup_holder");  	LLRect nearby_media_rect = mPanelNearByMedia->getRect();  	LLButton* nearby_media_btn =  getChild<LLButton>( "media_toggle_btn" ); -	LLRect nearby_media_btn_rect = nearby_media_btn->calcScreenRect(); +	LLRect nearby_media_btn_rect = nearby_media_btn->getRect();  	nearby_media_rect.setLeftTopAndSize(nearby_media_btn_rect.mLeft -   										(nearby_media_rect.getWidth() - nearby_media_btn_rect.getWidth())/2,  										nearby_media_btn_rect.mBottom, @@ -560,8 +558,11 @@ void LLStatusBar::onMouseEnterNearbyMedia()  	// show the master volume pull-down  	mPanelNearByMedia->setShape(nearby_media_rect); -	mPanelNearByMedia->setVisible(TRUE); +	LLUI::clearPopups(); +	LLUI::addPopup(mPanelNearByMedia); +  	mPanelVolumePulldown->setVisible(FALSE); +	mPanelNearByMedia->setVisible(TRUE);  } @@ -650,18 +651,6 @@ void LLStatusBar::onClickStatGraph(void* data)  	LLFloaterReg::showInstance("lagmeter");  } -void LLStatusBar::onClickScreen(S32 x, S32 y) -{ -	if (mPanelNearByMedia->getVisible()) -	{ -		LLRect screen_rect = mPanelNearByMedia->calcScreenRect(); -		if (!screen_rect.pointInRect(x, y)) -		{ -			mPanelNearByMedia->setVisible(FALSE); -		} -	} -} -  BOOL can_afford_transaction(S32 cost)  {  	return((cost <= 0)||((gStatusBar) && (gStatusBar->getBalance() >=cost))); diff --git a/indra/newview/lluploaddialog.cpp b/indra/newview/lluploaddialog.cpp index 577b5952e5..22c7d670f8 100644 --- a/indra/newview/lluploaddialog.cpp +++ b/indra/newview/lluploaddialog.cpp @@ -91,7 +91,7 @@ LLUploadDialog::LLUploadDialog( const std::string& msg)  	setMessage(msg);  	// The dialog view is a root view -	gFocusMgr.setTopCtrl( this ); +	gViewerWindow->addPopup(this);  }  void LLUploadDialog::setMessage( const std::string& msg) diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 30f2d2c41b..6c8900df21 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -131,6 +131,7 @@  #include "llmorphview.h"  #include "llmoveview.h"  #include "llnavigationbar.h" +#include "llpopupview.h"  #include "llpreviewtexture.h"  #include "llprogressview.h"  #include "llresmgr.h" @@ -690,23 +691,23 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window,  LLCoordGL pos, MASK  	}  	// Topmost view gets a chance before the hierarchy -	LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl(); -	if (top_ctrl) -	{ -		S32 local_x, local_y; -		top_ctrl->screenPointToLocal( x, y, &local_x, &local_y ); -		if (top_ctrl->pointInView(local_x, local_y)) -		{ -			return top_ctrl->handleAnyMouseClick(local_x, local_y, mask, clicktype, down)	; -		} -		else -		{ -			if (down) -			{ -				gFocusMgr.setTopCtrl(NULL); -			} -		} -	} +	//LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl(); +	//if (top_ctrl) +	//{ +	//	S32 local_x, local_y; +	//	top_ctrl->screenPointToLocal( x, y, &local_x, &local_y ); +	//		if (top_ctrl->pointInView(local_x, local_y)) +	//		{ +	//			return top_ctrl->handleAnyMouseClick(local_x, local_y, mask, clicktype, down)	; +	//		} +	//		else +	//		{ +	//		if (down) +	//		{ +	//			gFocusMgr.setTopCtrl(NULL); +	//		} +	//	} +	//}  	// Give the UI views a chance to process the click  	if( mRootView->handleAnyMouseClick(x, y, mask, clicktype, down) ) @@ -1552,11 +1553,13 @@ void LLViewerWindow::initBase()  	mWorldViewPlaceholder = main_view->getChildView("world_view_rect")->getHandle();  	mNonSideTrayView = main_view->getChildView("non_side_tray_view")->getHandle();  	mFloaterViewHolder = main_view->getChildView("floater_view_holder")->getHandle(); +	mPopupView = main_view->getChild<LLPopupView>("popup_holder");  	// Constrain floaters to inside the menu and status bar regions.  	gFloaterView = main_view->getChild<LLFloaterView>("Floater View");  	gSnapshotFloaterView = main_view->getChild<LLSnapshotFloaterView>("Snapshot Floater View"); +  	// Console  	llassert( !gConsole );  	LLConsole::Params cp; @@ -2426,6 +2429,30 @@ void LLViewerWindow::handleScrollWheel(S32 clicks)  	return;  } +void LLViewerWindow::addPopup(LLView* popup) +{ +	if (mPopupView) +	{ +		mPopupView->addPopup(popup); +	} +} + +void LLViewerWindow::removePopup(LLView* popup) +{ +	if (mPopupView) +	{ +		mPopupView->removePopup(popup); +	} +} + +void LLViewerWindow::clearPopups() +{ +	if (mPopupView) +	{ +		mPopupView->clearPopups(); +	} +} +  void LLViewerWindow::moveCursorToCenter()  {  	if (! gSavedSettings.getBOOL("DisableMouseWarp")) @@ -2554,6 +2581,33 @@ void LLViewerWindow::updateUI()  	}  	// aggregate visible views that contain mouse cursor in display order +	LLPopupView::popup_list_t popups = mPopupView->getCurrentPopups(); + +	for(LLPopupView::popup_list_t::iterator popup_it = popups.begin(); popup_it != popups.end(); ++popup_it) +	{ +		LLView* popup = popup_it->get(); +		if (popup && popup->calcScreenBoundingRect().pointInRect(x, y)) +		{ +			// iterator over contents of top_ctrl, and throw into mouse_hover_set +			for (LLView::tree_iterator_t it = popup->beginTreeDFS(); +				it != popup->endTreeDFS(); +				++it) +			{ +				LLView* viewp = *it; +				if (viewp->getVisible() +					&& viewp->calcScreenBoundingRect().pointInRect(x, y)) +				{ +					// we have a view that contains the mouse, add it to the set +					mouse_hover_set.insert(viewp->getHandle()); +				} +				else +				{ +					// skip this view and all of its children +					it.skipDescendants(); +				} +			} +		} +	}  	// while the top_ctrl contains the mouse cursor, only it and its descendants will receive onMouseEnter events  	if (top_ctrl && top_ctrl->calcScreenBoundingRect().pointInRect(x, y)) diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index bfce65f2ba..410445d97f 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -69,6 +69,7 @@ class LLHUDIcon;  class LLWindow;  class LLRootView;  class LLViewerWindowListener; +class LLPopupView;  #define PICK_HALF_WIDTH 5  #define PICK_DIAMETER (2 * PICK_HALF_WIDTH + 1) @@ -300,6 +301,11 @@ public:  	BOOL			handleKey(KEY key, MASK mask);  	void			handleScrollWheel	(S32 clicks); +	// add and remove views from "popup" layer +	void			addPopup(LLView* popup); +	void			removePopup(LLView* popup); +	void			clearPopups(); +  	// Hide normal UI when a logon fails, re-show everything when logon is attempted again  	void			setNormalControlsVisible( BOOL visible );  	void			setMenuBackgroundColor(bool god_mode = false, bool dev_grid = false); @@ -458,6 +464,7 @@ protected:  	LLHandle<LLView> mWorldViewPlaceholder;	// widget that spans the portion of screen dedicated to rendering the 3d world  	LLHandle<LLView> mNonSideTrayView;		// parent of world view + bottom bar, etc...everything but the side tray  	LLHandle<LLView> mFloaterViewHolder;	// container for floater_view +	LLPopupView*	mPopupView;			// container for transient popups  	class LLDebugText* mDebugText; // Internal class for debug text @@ -477,7 +484,7 @@ protected:  private:  	// Object temporarily hovered over while dragging  	LLPointer<LLViewerObject>	mDragHoveredObject; -};	 +};  void toggle_flying(void*);  void toggle_first_person(); diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml index 7b6081d7be..85853f39bb 100644 --- a/indra/newview/skins/default/xui/en/main_view.xml +++ b/indra/newview/skins/default/xui/en/main_view.xml @@ -156,18 +156,19 @@                     name="notify_container"                     tab_group="-2"                     width="1024"/> -  <menu_holder top="0" -               follows="all" -               height="768" -               mouse_opaque="false" -               name="Menu Holder" -               width="1024"/>    <panel top="0"           follows="all"           height="768"           mouse_opaque="false"           name="popup_holder" +         class="popup_holder"           width="1024"/> +  <menu_holder top="0" +               follows="all" +               height="768" +               mouse_opaque="false" +               name="Menu Holder" +               width="1024"/>    <snapshot_floater_view enabled="false"                           follows="all"                           height="768" | 
