diff options
39 files changed, 628 insertions, 267 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..d34083a384 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -73,9 +73,9 @@ S32 LLView::sLastBottomXML = S32_MIN; std::vector<LLViewDrawContext*> LLViewDrawContext::sDrawContextStack; -#if LL_DEBUG +//#if LL_DEBUG BOOL LLView::sIsDrawing = FALSE; -#endif +//#endif // Compiler optimization, generate extern template template class LLView* LLView::getChild<class LLView>( @@ -150,6 +150,10 @@ LLView::~LLView() { dirtyRect(); //llinfos << "Deleting view " << mName << ":" << (void*) this << llendl; + if (LLView::sIsDrawing) + { + llwarns << "Deleting view " << mName << " during UI draw() phase" << llendl; + } // llassert(LLView::sIsDrawing == FALSE); // llassert_always(sDepth == 0); // avoid deleting views while drawing! It can subtly break list iterators @@ -592,11 +596,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/llui/llview.h b/indra/llui/llview.h index c4d7313743..efae00f0e5 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -171,9 +171,9 @@ private: // widgets in general are not copyable LLView(const LLView& other) {}; public: -#if LL_DEBUG +//#if LL_DEBUG static BOOL sIsDrawing; -#endif +//#endif enum ESoundFlags { SILENT = 0, diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index dd45662b07..d2cddd39f7 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -355,6 +355,7 @@ set(viewer_SOURCE_FILES llpatchvertexarray.cpp llplacesinventorybridge.cpp llplacesinventorypanel.cpp + llpopupview.cpp llpolymesh.cpp llpolymorph.cpp llpreview.cpp @@ -856,6 +857,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 b1db7bf481..33ab12c623 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -704,9 +704,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/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index f8f8f50cd6..80d9b14345 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -392,7 +392,12 @@ void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze) _exit(1); } - // TODO:palmer REMOVE THIS VERY SOON. THIS WILL NOT BE IN VIEWER 2.0 + // TODO from palmer: Find a better way to handle managing old crash logs + // when this is a separate imbedable module. Ideally just sort crash stack + // logs based on date, and grab the latest one as opposed to deleting them + // for thoughts on what the module would look like. + // See: https://wiki.lindenlab.com/wiki/Viewer_Crash_Reporter_Round_4 + // Remove the crash stack log from previous executions. // Since we've started logging a new instance of the app, we can assume // The old crash stack is invalid for the next crash report. 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..1668a91eed --- /dev/null +++ b/indra/newview/llpopupview.cpp @@ -0,0 +1,250 @@ +/** + * @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) + { + popup_list_t::iterator iter = std::find(mPopups.begin(), mPopups.end(), popup->getHandle()); + if(iter != mPopups.end()) + { + mPopups.erase(iter); + } + mPopups.push_front(popup->getHandle()); + } +} + +void LLPopupView::removePopup(LLView* popup) +{ + if (popup) + { + if (gFocusMgr.childHasKeyboardFocus(popup)) + { + gFocusMgr.setKeyboardFocus(NULL); + } + popup_list_t::iterator iter = std::find(mPopups.begin(), mPopups.end(), popup->getHandle()); + if(iter != mPopups.end()) + { + mPopups.erase(iter); + } + 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 0c94469e38..1c762e2132 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" @@ -734,23 +735,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) ) @@ -1596,11 +1597,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; @@ -2062,9 +2065,9 @@ void LLViewerWindow::drawDebugText() void LLViewerWindow::draw() { -#if LL_DEBUG +//#if LL_DEBUG LLView::sIsDrawing = TRUE; -#endif +//#endif stop_glerror(); LLUI::setLineWidth(1.f); @@ -2176,9 +2179,9 @@ void LLViewerWindow::draw() LLUI::popMatrix(); gGL.popMatrix(); -#if LL_DEBUG +//#if LL_DEBUG LLView::sIsDrawing = FALSE; -#endif +//#endif } // Takes a single keydown event, usually when UI is visible @@ -2470,6 +2473,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")) @@ -2598,6 +2625,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/de/floater_buy_currency.xml b/indra/newview/skins/default/xui/de/floater_buy_currency.xml index 4bf4692e36..d0d3628448 100644 --- a/indra/newview/skins/default/xui/de/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/de/floater_buy_currency.xml @@ -18,13 +18,13 @@ <text name="balance_amount"> [AMT] L$ </text> - <text name="currency_action" width="90"> + <text name="currency_action"> Ich möchte kaufen </text> <text name="currency_label"> L$ </text> - <line_editor label="L$" left_delta="55" name="currency_amt"> + <line_editor label="L$" name="currency_amt"> 1234 </line_editor> <text name="buying_label"> diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index 29c6ae8009..3297150c7f 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -395,7 +395,7 @@ Leyla Linden </text> name="Cancel Land Sale" left_pad="5" top_pad="-25" - width="145" /> + width="155" /> <text type="string" length="1" @@ -1504,7 +1504,7 @@ Only large parcels can be listed in search. name="Clear" tool_tip="Clear the landing point" right="-10" - width="50" /> + width="55" /> <text type="string" length="1" diff --git a/indra/newview/skins/default/xui/en/floater_customize.xml b/indra/newview/skins/default/xui/en/floater_customize.xml index fd10938539..6f2b0fc3ea 100644 --- a/indra/newview/skins/default/xui/en/floater_customize.xml +++ b/indra/newview/skins/default/xui/en/floater_customize.xml @@ -307,7 +307,7 @@ label_selected="Save" layout="topleft" name="Save" - right="190" + right="186" top="477" width="82" /> <button @@ -319,7 +319,7 @@ name="Save As" top="477" right="304" - width="110" /> + width="115" /> </panel> <panel border="false" @@ -489,7 +489,7 @@ height="23" layout="topleft" name="Item Action Label" - right="132" + right="90" width="100"> Skin: </text> @@ -548,7 +548,7 @@ label="Save" label_selected="Save" layout="topleft" - right="218" + right="186" name="Save" top="477" width="82" /> @@ -561,7 +561,7 @@ right="304" name="Save As" top="477" - width="82" /> + width="115" /> <button follows="right|bottom" height="23" @@ -739,7 +739,7 @@ height="23" layout="topleft" name="Item Action Label" - right="132" + right="90" width="100"> Hair: </text> @@ -771,7 +771,7 @@ label="Save" label_selected="Save" layout="topleft" - right="218" + right="186" name="Save" top="477" width="82" /> @@ -784,7 +784,7 @@ right="304" name="Save As" top="477" - width="82" /> + width="115" /> <button follows="right|bottom" height="23" @@ -924,7 +924,7 @@ height="23" layout="bottomleft" name="Item Action Label" - right="132" + right="90" width="100"> Eyes: </text> @@ -955,7 +955,7 @@ label="Save" label_selected="Save" layout="topleft" - right="218" + right="186" name="Save" top="477" width="82" /> @@ -968,7 +968,7 @@ right="304" name="Save As" top="477" - width="82" /> + width="115" /> <button follows="right|bottom" height="23" @@ -1069,7 +1069,7 @@ label="Save" label_selected="Save" layout="topleft" - right="218" + right="186" name="Save" top="477" width="82" /> @@ -1082,7 +1082,7 @@ right="304" name="Save As" top="477" - width="82" /> + width="115" /> <button follows="right|bottom" height="23" @@ -1193,7 +1193,7 @@ height="23" layout="bottomleft" name="Item Action Label" - right="132" + right="90" width="100"> Shirt: </text> @@ -1272,7 +1272,7 @@ label="Save" label_selected="Save" layout="topleft" - right="218" + right="186" name="Save" top="477" width="82" /> @@ -1285,7 +1285,7 @@ right="304" name="Save As" top="477" - width="82" /> + width="115" /> <button follows="right|bottom" height="23" @@ -1396,7 +1396,7 @@ height="23" layout="bottomleft" name="Item Action Label" - right="132" + right="90" width="100"> Pants: </text> @@ -1538,7 +1538,7 @@ height="23" layout="bottomleft" name="Item Action Label" - right="132" + right="90" width="100"> Shoes: </text> @@ -1579,7 +1579,7 @@ label="Save" label_selected="Save" layout="topleft" - right="218" + right="186" name="Save" top="477" width="82" /> @@ -1592,7 +1592,7 @@ right="304" name="Save As" top="477" - width="82" /> + width="115" /> <button follows="right|bottom" height="23" @@ -1741,7 +1741,7 @@ height="23" layout="bottomleft" name="Item Action Label" - right="132" + right="90" width="100"> Socks: </text> @@ -1782,7 +1782,7 @@ label="Save" label_selected="Save" layout="topleft" - right="218" + right="186" name="Save" top="477" width="82" /> @@ -1795,7 +1795,7 @@ right="304" name="Save As" top="477" - width="82" /> + width="115" /> <button follows="right|bottom" height="23" @@ -1944,7 +1944,7 @@ height="23" layout="bottomleft" name="Item Action Label" - right="132" + right="90" width="100"> Jacket: </text> @@ -1996,7 +1996,7 @@ label="Save" label_selected="Save" layout="topleft" - right="218" + right="186" name="Save" top="477" width="82" /> @@ -2009,7 +2009,7 @@ right="304" name="Save As" top="477" - width="82" /> + width="115" /> <button follows="right|bottom" height="23" @@ -2158,7 +2158,7 @@ height="23" layout="bottomleft" name="Item Action Label" - right="132" + right="90" width="100"> Gloves: </text> @@ -2199,7 +2199,7 @@ label="Save" label_selected="Save" layout="topleft" - right="218" + right="186" name="Save" top="477" width="82" /> @@ -2212,7 +2212,7 @@ right="304" name="Save As" top="477" - width="82" /> + width="115" /> <button follows="right|bottom" height="23" @@ -2361,7 +2361,7 @@ height="23" layout="bottomleft" name="Item Action Label" - right="132" + right="90" width="100"> Undershirt: </text> @@ -2402,7 +2402,7 @@ label="Save" label_selected="Save" layout="topleft" - right="218" + right="186" name="Save" top="477" width="82" /> @@ -2415,7 +2415,7 @@ right="304" name="Save As" top="477" - width="82" /> + width="115" /> <button follows="right|bottom" height="23" @@ -2564,7 +2564,7 @@ height="23" layout="bottomleft" name="Item Action Label" - right="132" + right="90" width="100"> Underpants: </text> @@ -2605,7 +2605,7 @@ label="Save" label_selected="Save" layout="topleft" - right="218" + right="186" name="Save" top="477" width="82" /> @@ -2618,7 +2618,7 @@ right="304" name="Save As" top="477" - width="82" /> + width="115" /> <button follows="right|bottom" height="23" @@ -2767,7 +2767,7 @@ height="23" layout="bottomleft" name="Item Action Label" - right="132" + right="90" width="100"> Skirt: </text> @@ -2808,7 +2808,7 @@ label="Save" label_selected="Save" layout="topleft" - right="218" + right="186" name="Save" top="477" width="82" /> @@ -2821,7 +2821,7 @@ right="304" name="Save As" top="477" - width="82" /> + width="115" /> <button follows="right|bottom" height="23" @@ -2970,7 +2970,7 @@ height="23" layout="bottomleft" name="Item Action Label" - right="132" + right="90" width="100"> Tattoo: </text> @@ -3024,7 +3024,7 @@ label="Save" label_selected="Save" layout="topleft" - right="218" + right="186" name="Save" top="477" width="82" /> @@ -3037,7 +3037,7 @@ right="304" name="Save As" top="477" - width="82" /> + width="115" /> <button follows="right|bottom" height="23" @@ -3186,7 +3186,7 @@ height="23" layout="bottomleft" name="Item Action Label" - right="132" + right="90" width="100"> Alpha: </text> @@ -3305,7 +3305,7 @@ label="Save" label_selected="Save" layout="topleft" - right="218" + right="186" name="Save" top="477" width="82" /> @@ -3318,7 +3318,7 @@ right="304" name="Save As" top="477" - width="82" /> + width="115" /> <button follows="right|bottom" height="23" diff --git a/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml index 990be55847..1f192f9b28 100644 --- a/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml +++ b/indra/newview/skins/default/xui/en/floater_live_lsleditor.xml @@ -45,9 +45,9 @@ layout="topleft" name="Reset" left="10" - width="61" /> + width="85" /> <check_box - left_delta="71" + left_delta="90" top_delta="3" enabled="false" follows="left|bottom" @@ -57,9 +57,9 @@ label="Running" layout="topleft" name="running" - width="100" /> + width="205" /> <check_box - left_delta="75" + left_delta="140" enabled="true" follows="left|bottom" font="SansSerif" diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml index 01548dd820..dda14f02ff 100644 --- a/indra/newview/skins/default/xui/en/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml @@ -45,7 +45,7 @@ </radio_group> <ui_ctrl height="90" - width="90" + width="125" layout="topleft" name="thumbnail_placeholder" top_pad="6" @@ -149,7 +149,7 @@ left="10" name="type_label2" top_pad="5" - width="120"> + width="127"> Size </text> <text @@ -199,7 +199,7 @@ left_delta="0" name="texture_size_combo" top_delta="0" - width="120"> + width="127"> <combo_box.item label="Current Window" name="CurrentWindow" @@ -228,7 +228,7 @@ left_delta="0" name="local_size_combo" top_delta="0" - width="120"> + width="127"> <combo_box.item label="Current Window" name="CurrentWindow" 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" diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml index d14355b9f4..d444420550 100644 --- a/indra/newview/skins/default/xui/en/panel_script_ed.xml +++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml @@ -178,5 +178,5 @@ top_pad="-35" right="487" name="Save_btn" - width="61" /> + width="81" /> </panel> diff --git a/indra/newview/skins/default/xui/fr/floater_about_land.xml b/indra/newview/skins/default/xui/fr/floater_about_land.xml index e7e2d8a0ee..d0e96583f0 100644 --- a/indra/newview/skins/default/xui/fr/floater_about_land.xml +++ b/indra/newview/skins/default/xui/fr/floater_about_land.xml @@ -109,7 +109,7 @@ <text name="Selling with no objects in parcel."> Objets non inclus dans la vente </text> - <button label="Annuler la vente du terrain" label_selected="Annuler la vente du terrain" left="275" name="Cancel Land Sale" width="165"/> + <button label="Annuler la vente du terrain" label_selected="Annuler la vente du terrain" name="Cancel Land Sale"/> <text name="Claimed:"> Acquis : </text> @@ -312,17 +312,17 @@ Seules les parcelles de grande taille peuvent apparaître dans la recherche. </text> <check_box label="Modifier le terrain" name="edit land check" tool_tip="Si cette option est cochée, n'importe qui peut terraformer votre terrain. Il vaut mieux ne pas cocher cette option pour toujours pouvoir modifer votre propre terrain."/> <check_box label="Voler" name="check fly" tool_tip="Si cette option est cochée, les résidents peuvent voler sur votre terrain. Si elle n'est pas cochée, ils ne pourront voler que lorsqu'ils arrivent et passent au dessus de votre terrain."/> - <text left="152" name="allow_label2"> + <text name="allow_label2"> Construire : </text> <check_box label="Tous" left="285" name="edit objects check"/> <check_box label="Groupe" left="395" name="edit group objects check"/> - <text left="152" name="allow_label3" width="150"> + <text name="allow_label3"> Laisser entrer des objets : </text> <check_box label="Tous" left="285" name="all object entry check"/> <check_box label="Groupe" left="395" name="group object entry check"/> - <text left="152" name="allow_label4"> + <text name="allow_label4"> Exécuter des scripts : </text> <check_box label="Tous" left="285" name="check other scripts"/> @@ -367,11 +367,11 @@ Seules les parcelles de grande taille peuvent apparaître dans la recherche. Photo : </text> <texture_picker bottom="-319" label="" name="snapshot_ctrl" tool_tip="Cliquez pour sélectionner une image"/> - <text bottom="-323" name="landing_point"> + <text name="landing_point"> Lieu d'arrivée : [LANDING] </text> - <button bottom="-323" label="Définir" label_selected="Définir" name="Set" tool_tip="Définit le point d'arrivée des visiteurs. Définit l'emplacement de votre avatar sur ce terrain."/> - <button bottom="-323" label="Annuler" label_selected="Annuler" name="Clear" tool_tip="Effacer le lieu d'arrivée"/> + <button label="Définir" label_selected="Définir" name="Set" tool_tip="Définit le point d'arrivée des visiteurs. Définit l'emplacement de votre avatar sur ce terrain."/> + <button label="Annuler" label_selected="Annuler" name="Clear" tool_tip="Effacer le lieu d'arrivée"/> <text bottom="-343" name="Teleport Routing: "> Règles de téléportation : </text> @@ -380,7 +380,7 @@ Seules les parcelles de grande taille peuvent apparaître dans la recherche. <combo_box.item label="Lieu d'arrivée fixe" name="LandingPoint"/> <combo_box.item label="Lieu d'arrivée libre" name="Anywhere"/> </combo_box> - </panel> + </panel> <panel label="MÉDIA" name="land_media_panel"> <text name="with media:" width="85"> Type : diff --git a/indra/newview/skins/default/xui/fr/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/fr/floater_live_lsleditor.xml index feb2fe1027..7647452e91 100644 --- a/indra/newview/skins/default/xui/fr/floater_live_lsleditor.xml +++ b/indra/newview/skins/default/xui/fr/floater_live_lsleditor.xml @@ -9,7 +9,7 @@ <floater.string name="Title"> SCRIPT : [NAME] </floater.string> - <button label="Réinitialiser" label_selected="Réinitialiser" left="390" name="Reset" width="100"/> - <check_box initial_value="true" label="Exécution en cours" left="4" name="running"/> - <check_box initial_value="true" label="Mono" left_delta="160" name="mono"/> + <button label="Réinitialiser" label_selected="Réinitialiser" name="Reset"/> + <check_box initial_value="true" label="Exécution en cours" name="running"/> + <check_box initial_value="true" label="Mono" name="mono"/> </floater> diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp index 6b275bbcad..e5a846f15a 100644 --- a/indra/test_apps/llplugintest/llmediaplugintest.cpp +++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp @@ -307,7 +307,7 @@ GLfloat LLMediaPluginTest::distanceToCamera( GLfloat point_x, GLfloat point_y, G GLdouble modelMatrix[16]; GLdouble projMatrix[16]; - int viewport[4]; + GLint viewport[4]; glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); glGetDoublev(GL_PROJECTION_MATRIX, projMatrix); |