From 41a30a59fb1b6dea2d531333d0429632f1fef2fe Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Tue, 2 Mar 2010 14:21:58 -0800 Subject: initial work changing topctrl to popup layer --- indra/llui/llcombobox.cpp | 7 ++----- indra/llui/llfloater.cpp | 15 +++----------- indra/llui/llfocusmgr.cpp | 47 +++----------------------------------------- indra/llui/llfocusmgr.h | 8 +------- indra/llui/llhandle.h | 7 +++++++ indra/llui/llmodaldialog.cpp | 6 +++--- indra/llui/llui.cpp | 29 +++++++++++++++++++++++++++ indra/llui/llui.h | 10 ++++++++++ indra/llui/llview.cpp | 5 ----- 9 files changed, 58 insertions(+), 76 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index 9d23daf56d..de3bf719ee 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -615,7 +615,7 @@ void LLComboBox::showList() // register ourselves as a "top" control // effectively putting us into a special draw layer // and not affecting the bounding rectangle calculation - gFocusMgr.setTopCtrl(this); + LLUI::addPopup(this); // Show the list and push the button down mButton->setToggleState(TRUE); @@ -644,10 +644,7 @@ void LLComboBox::hideList() mList->mouseOverHighlightNthItem(-1); setUseBoundingRect(FALSE); - if( gFocusMgr.getTopCtrl() == this ) - { - gFocusMgr.setTopCtrl(NULL); - } + LLUI::removePopup(this); } } diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index b6d73cda3c..b93b72abf6 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); @@ -2503,10 +2497,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..ad2940e685 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(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 } } diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h index 83ecd1d301..5b08c628d4 100644 --- a/indra/llui/llfocusmgr.h +++ b/indra/llui/llfocusmgr.h @@ -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 > 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 + LLHandle& operator =(const LLHandle& 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..64df1dbc7a 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -86,6 +86,9 @@ std::list gUntranslated; /*static*/ LLHelp* LLUI::sHelpImpl = NULL; /*static*/ std::vector 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 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,25 @@ 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 // 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..824d76f526 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -160,12 +160,17 @@ public: // Methods // typedef std::map settings_map_t; + typedef boost::function add_popup_t; + typedef boost::function remove_popup_t; + typedef boost::function 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(); @@ -207,6 +212,8 @@ public: static F32 getMouseIdleTime() { return sMouseIdleTimer.getElapsedTimeF32(); } static void resetMouseIdleTimer() { sMouseIdleTimer.reset(); } static LLWindow* getWindow() { return sWindow; } + static void addPopup(LLView*); + static void removePopup(LLView*); // Ensures view does not overlap mouse cursor, but is inside // the view's parent rectangle. Used for tooltips, inspectors. @@ -227,6 +234,9 @@ private: static LLImageProviderInterface* sImageProvider; static std::vector 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 -- cgit v1.3 From 69f9c0bcf9764a1b682bfdd5baa3f340922dcbaa Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 3 Mar 2010 19:37:41 -0800 Subject: WIP - replace top ctrl with LLPopupView --- indra/llui/llcombobox.cpp | 14 ++++++++------ indra/llui/llcombobox.h | 1 + indra/llui/llfloater.cpp | 2 +- indra/llui/llfocusmgr.cpp | 4 ++-- indra/llui/llfocusmgr.h | 2 +- indra/llui/llui.cpp | 9 +++++++++ indra/llui/llui.h | 2 ++ indra/newview/llpanelnearbymedia.cpp | 9 +++++++++ indra/newview/llpanelnearbymedia.h | 1 + indra/newview/llpanelvolumepulldown.cpp | 14 ++++++++------ indra/newview/llpanelvolumepulldown.h | 2 +- indra/newview/llpopupview.cpp | 18 ++++++++++++++++-- indra/newview/llpopupview.h | 4 +++- indra/newview/llstatusbar.cpp | 33 +++++++++++---------------------- indra/newview/llviewerwindow.cpp | 27 +++++++++++++++++++++++++++ 15 files changed, 100 insertions(+), 42 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index de3bf719ee..c679717807 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 - LLUI::addPopup(this); - // Show the list and push the button down mButton->setToggleState(TRUE); mList->setVisible(TRUE); + LLUI::addPopup(this); + setUseBoundingRect(TRUE); + updateBoundingRect(); } void LLComboBox::hideList() @@ -645,6 +646,7 @@ void LLComboBox::hideList() setUseBoundingRect(FALSE); LLUI::removePopup(this); + updateBoundingRect(); } } diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index 4f27588467..aa1e708bec 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -231,5 +231,6 @@ private: commit_callback_t mTextEntryCallback; commit_callback_t mSelectionCallback; S32 mLastSelectedIndex; + boost::signals2::connection mTopLostSignalConnection; }; #endif diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index b93b72abf6..c45be34d43 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1354,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); } diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp index ad2940e685..b3af258456 100644 --- a/indra/llui/llfocusmgr.cpp +++ b/indra/llui/llfocusmgr.cpp @@ -437,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 5b08c628d4..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; diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 64df1dbc7a..5121ef5351 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -1905,6 +1905,15 @@ void LLUI::removePopup(LLView* viewp) } } +//static +void LLUI::clearPopups() +{ + if (sClearPopupsFunc) + { + sClearPopupsFunc(); + } +} + //static // spawn_x and spawn_y are top left corner of view in screen GL coordinates diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 824d76f526..30f3623ded 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -212,8 +212,10 @@ public: static F32 getMouseIdleTime() { return sMouseIdleTimer.getElapsedTimeF32(); } 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. diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp index 41e37a9b1b..4bbecc4799 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"); @@ -187,6 +189,13 @@ void LLPanelNearByMedia::onMouseLeave(S32 x, S32 y, MASK mask) LLPanel::onMouseLeave(x,y,mask); } +/*virtual*/ +void LLPanelNearByMedia::onTopLost() +{ + setVisible(FALSE); +} + + /*virtual*/ void LLPanelNearByMedia::handleVisibilityChange ( BOOL new_visibility ) { diff --git a/indra/newview/llpanelnearbymedia.h b/indra/newview/llpanelnearbymedia.h index 809a8d81a1..af4659365f 100644 --- a/indra/newview/llpanelnearbymedia.h +++ b/indra/newview/llpanelnearbymedia.h @@ -53,6 +53,7 @@ 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 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 index 964ca4d361..eb750a87e2 100644 --- a/indra/newview/llpopupview.cpp +++ b/indra/newview/llpopupview.cpp @@ -100,7 +100,7 @@ BOOL LLPopupView::handleMouseEvent(boost::function func S32 popup_x, popup_y; if (localPointToOtherView(x, y, &popup_x, &popup_y, popup) - && popup->getRect().pointInRect(popup_x, popup_y)) + && popup->pointInView(popup_x, popup_y)) { if (func(popup, popup_x, popup_y)) { @@ -180,9 +180,9 @@ BOOL LLPopupView::handleToolTip(S32 x, S32 y, MASK mask) void LLPopupView::addPopup(LLView* popup) { - removePopup(popup); if (popup) { + mPopups.erase(std::find(mPopups.begin(), mPopups.end(), popup->getHandle())); mPopups.push_back(popup->getHandle()); } } @@ -191,12 +191,26 @@ void LLPopupView::removePopup(LLView* popup) { if (popup) { + if (gFocusMgr.childHasKeyboardFocus(popup)) + { + gFocusMgr.setKeyboardFocus(NULL); + } + popup->onTopLost(); mPopups.erase(std::find(mPopups.begin(), mPopups.end(), popup->getHandle())); } } void LLPopupView::clearPopups() { + for (popup_list_t::iterator popup_it = mPopups.begin(); + popup_it != mPopups.end();) + { + LLView* popup = popup_it->get(); + ++popup_it; + + if (popup) popup->onTopLost(); + } + mPopups.clear(); } diff --git a/indra/newview/llpopupview.h b/indra/newview/llpopupview.h index 591e033161..c5dbb94c4c 100644 --- a/indra/newview/llpopupview.h +++ b/indra/newview/llpopupview.h @@ -56,9 +56,11 @@ public: void removePopup(LLView* popup); void clearPopups(); + typedef std::list > popup_list_t; + popup_list_t getCurrentPopups() { return mPopups; } + private: BOOL handleMouseEvent(boost::function, boost::function, S32 x, S32 y); - typedef std::list > popup_list_t; popup_list_t mPopups; }; #endif //LL_LLROOTVIEW_H diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 732c23982b..2ed0718e41 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; } @@ -538,8 +534,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() @@ -558,8 +556,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); } @@ -648,18 +649,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/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 5bd79c67c3..1304a66397 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2590,6 +2590,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)) -- cgit v1.3 From 485711e179e0ccf6351feb02318f41bbb5593662 Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Thu, 4 Mar 2010 16:35:52 -0800 Subject: removed extraneous updateBoundingRect() calls remove the login progress panel as a popup only after it has finished fading out popupview manages it's own registering and unregistering of popup callbacks --- indra/llui/llcombobox.cpp | 4 ++-- indra/newview/llpopupview.cpp | 10 +++++++++- indra/newview/llpopupview.h | 1 + indra/newview/llprogressview.cpp | 3 ++- indra/newview/llviewerwindow.cpp | 2 -- 5 files changed, 14 insertions(+), 6 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index c679717807..9ec1a9f7c4 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -622,7 +622,7 @@ void LLComboBox::showList() LLUI::addPopup(this); setUseBoundingRect(TRUE); - updateBoundingRect(); +// updateBoundingRect(); } void LLComboBox::hideList() @@ -646,7 +646,7 @@ void LLComboBox::hideList() setUseBoundingRect(FALSE); LLUI::removePopup(this); - updateBoundingRect(); +// updateBoundingRect(); } } diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp index d9e4ebcd3c..590a45c96c 100644 --- a/indra/newview/llpopupview.cpp +++ b/indra/newview/llpopupview.cpp @@ -48,6 +48,14 @@ bool view_visible(LLView* viewp) 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() @@ -212,8 +220,8 @@ void LLPopupView::removePopup(LLView* popup) { gFocusMgr.setKeyboardFocus(NULL); } - popup->onTopLost(); mPopups.erase(std::find(mPopups.begin(), mPopups.end(), popup->getHandle())); + popup->onTopLost(); } } diff --git a/indra/newview/llpopupview.h b/indra/newview/llpopupview.h index 6248e9a553..1ec61d5450 100644 --- a/indra/newview/llpopupview.h +++ b/indra/newview/llpopupview.h @@ -39,6 +39,7 @@ class LLPopupView : public LLPanel { public: LLPopupView(); + ~LLPopupView(); /*virtual*/ void draw(); /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index 15831d85a0..120b584cd9 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -128,7 +128,6 @@ void LLProgressView::setVisible(BOOL visible) { if (getVisible() && !visible) { - gViewerWindow->removePopup(this); mFadeTimer.start(); } @@ -190,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/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 1304a66397..7dd606ccda 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1368,8 +1368,6 @@ LLViewerWindow::LLViewerWindow( LLNotifications::instance().setIgnoreAllNotifications(gSavedSettings.getBOOL("IgnoreAllNotifications")); llinfos << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << llendl; - LLUI::setPopupFuncs(boost::bind(&LLViewerWindow::addPopup, this, _1), boost::bind(&LLViewerWindow::removePopup, this, _1), boost::bind(&LLViewerWindow::clearPopups, this)); - // Default to application directory. LLViewerWindow::sSnapshotBaseName = "Snapshot"; LLViewerWindow::sMovieBaseName = "SLmovie"; -- cgit v1.3 From 7cea645ba2b77d5bbcba7a7189aa584ac95ff453 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 5 Mar 2010 17:38:21 -0800 Subject: added some logging to help track down crash in EXT-5849 --- indra/llui/llview.cpp | 8 ++++++-- indra/llui/llview.h | 4 ++-- indra/newview/llviewerwindow.cpp | 8 ++++---- 3 files changed, 12 insertions(+), 8 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index db2c460eec..b695731a02 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -73,9 +73,9 @@ S32 LLView::sLastBottomXML = S32_MIN; std::vector LLViewDrawContext::sDrawContextStack; -#if LL_DEBUG +//#if LL_DEBUG BOOL LLView::sIsDrawing = FALSE; -#endif +//#endif // Compiler optimization, generate extern template template class LLView* LLView::getChild( @@ -150,6 +150,10 @@ LLView::~LLView() { dirtyRect(); //llinfos << "Deleting view " << mName << ":" << (void*) this << llendl; + if (LLView::isDrawing) + { + 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 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/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 6c8900df21..d0a1a31ebd 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2021,9 +2021,9 @@ void LLViewerWindow::drawDebugText() void LLViewerWindow::draw() { -#if LL_DEBUG +//#if LL_DEBUG LLView::sIsDrawing = TRUE; -#endif +//#endif stop_glerror(); LLUI::setLineWidth(1.f); @@ -2135,9 +2135,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 -- cgit v1.3 From 4ada9e7f15eed6a462f22a119a724f64799aba54 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 5 Mar 2010 18:19:29 -0800 Subject: fix --- indra/llui/llview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index b695731a02..d34083a384 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -150,7 +150,7 @@ LLView::~LLView() { dirtyRect(); //llinfos << "Deleting view " << mName << ":" << (void*) this << llendl; - if (LLView::isDrawing) + if (LLView::sIsDrawing) { llwarns << "Deleting view " << mName << " during UI draw() phase" << llendl; } -- cgit v1.3