From c3c04adaa56c895018e1d2dd32b94469aaf44347 Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Tue, 2 Mar 2010 15:11:56 -0800 Subject: added missing files --- indra/newview/llpopupview.cpp | 202 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 indra/newview/llpopupview.cpp (limited to 'indra/newview/llpopupview.cpp') diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp new file mode 100644 index 0000000000..964ca4d361 --- /dev/null +++ b/indra/newview/llpopupview.cpp @@ -0,0 +1,202 @@ +/** + * @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 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() +{ +} + +void LLPopupView::draw() +{ + S32 screen_x, screen_y; + + for (popup_list_t::iterator popup_it = mPopups.begin(); + popup_it != mPopups.end();) + { + LLView* popup = popup_it->get(); + if (!popup) + { + popup_list_t::iterator cur_popup_it = popup_it; + ++popup_it; + mPopups.erase(cur_popup_it); + continue; + } + + 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 func, + boost::function predicate, + S32 x, S32 y) +{ + for (popup_list_t::reverse_iterator popup_it = mPopups.rbegin(); + popup_it != mPopups.rend(); + ++popup_it) + { + LLView* popup = popup_it->get(); + if (!popup + || !predicate(popup)) + { + continue; + } + + S32 popup_x, popup_y; + if (localPointToOtherView(x, y, &popup_x, &popup_y, popup) + && popup->getRect().pointInRect(popup_x, popup_y)) + { + if (func(popup, popup_x, popup_y)) + { + return TRUE; + } + } + } + + 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)) + { + clearPopups(); + 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); +} + +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)) + { + clearPopups(); + 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); +} + +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)) + { + clearPopups(); + 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); +} + +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); +} + +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); +} + +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); +} + +BOOL LLPopupView::handleToolTip(S32 x, S32 y, MASK mask) +{ + return handleMouseEvent(boost::bind(&LLMouseHandler::handleToolTip, _1, _2, _3, mask), view_visible, x, y); +} + +void LLPopupView::addPopup(LLView* popup) +{ + removePopup(popup); + if (popup) + { + mPopups.push_back(popup->getHandle()); + } +} + +void LLPopupView::removePopup(LLView* popup) +{ + if (popup) + { + mPopups.erase(std::find(mPopups.begin(), mPopups.end(), popup->getHandle())); + } +} + +void LLPopupView::clearPopups() +{ + mPopups.clear(); +} + -- 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/newview/llpopupview.cpp') 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 0bbcb0d22d2a215e0d8bf824b44a18a8bd948f20 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 3 Mar 2010 20:23:26 -0800 Subject: resizing and nesting of popups now work --- indra/newview/llpopupview.cpp | 64 +++++++++++++++++++++++++------------------ indra/newview/llpopupview.h | 2 +- indra/newview/llstatusbar.cpp | 10 +++---- 3 files changed, 43 insertions(+), 33 deletions(-) (limited to 'indra/newview/llpopupview.cpp') diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp index eb750a87e2..3494522969 100644 --- a/indra/newview/llpopupview.cpp +++ b/indra/newview/llpopupview.cpp @@ -54,17 +54,25 @@ void LLPopupView::draw() { S32 screen_x, screen_y; + // remove dead popups for (popup_list_t::iterator popup_it = mPopups.begin(); popup_it != mPopups.end();) { - LLView* popup = popup_it->get(); - if (!popup) + if (!popup_it->get()) { - popup_list_t::iterator cur_popup_it = popup_it; - ++popup_it; - mPopups.erase(cur_popup_it); - continue; + 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()) { @@ -85,16 +93,17 @@ void LLPopupView::draw() BOOL LLPopupView::handleMouseEvent(boost::function func, boost::function predicate, - S32 x, S32 y) + S32 x, S32 y, + bool close_popups) { - for (popup_list_t::reverse_iterator popup_it = mPopups.rbegin(); - popup_it != mPopups.rend(); - ++popup_it) + 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; } @@ -107,6 +116,9 @@ BOOL LLPopupView::handleMouseEvent(boost::function func return TRUE; } } + + popup->onTopLost(); + mPopups.erase(popup_it++); } return FALSE; @@ -115,9 +127,8 @@ BOOL LLPopupView::handleMouseEvent(boost::function func 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)) + if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true)) { - clearPopups(); return FALSE; } return TRUE; @@ -125,14 +136,13 @@ BOOL LLPopupView::handleMouseDown(S32 x, S32 y, MASK mask) 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); + 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)) + if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleMiddleMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true)) { - clearPopups(); return FALSE; } return TRUE; @@ -140,14 +150,13 @@ BOOL LLPopupView::handleMiddleMouseDown(S32 x, S32 y, MASK mask) 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); + 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)) + if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleRightMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true)) { - clearPopups(); return FALSE; } return TRUE; @@ -155,27 +164,27 @@ BOOL LLPopupView::handleRightMouseDown(S32 x, S32 y, MASK mask) 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); + 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); + 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); + 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); + 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); + return handleMouseEvent(boost::bind(&LLMouseHandler::handleToolTip, _1, _2, _3, mask), view_visible, x, y, false); } void LLPopupView::addPopup(LLView* popup) @@ -183,7 +192,7 @@ void LLPopupView::addPopup(LLView* popup) if (popup) { mPopups.erase(std::find(mPopups.begin(), mPopups.end(), popup->getHandle())); - mPopups.push_back(popup->getHandle()); + mPopups.push_front(popup->getHandle()); } } @@ -206,11 +215,12 @@ void LLPopupView::clearPopups() popup_it != mPopups.end();) { LLView* popup = popup_it->get(); + + popup_list_t::iterator cur_popup_it = popup_it; ++popup_it; - if (popup) popup->onTopLost(); + mPopups.erase(cur_popup_it); + popup->onTopLost(); } - - mPopups.clear(); } diff --git a/indra/newview/llpopupview.h b/indra/newview/llpopupview.h index c5dbb94c4c..6248e9a553 100644 --- a/indra/newview/llpopupview.h +++ b/indra/newview/llpopupview.h @@ -60,7 +60,7 @@ public: popup_list_t getCurrentPopups() { return mPopups; } private: - BOOL handleMouseEvent(boost::function, boost::function, S32 x, S32 y); + BOOL handleMouseEvent(boost::function, boost::function, S32 x, S32 y, bool close_popups); popup_list_t mPopups; }; #endif //LL_LLROOTVIEW_H diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 2ed0718e41..0a30ed0ecf 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -522,11 +522,11 @@ static void onClickScriptDebug(void*) void LLStatusBar::onMouseEnterVolume() { LLButton* volbtn = getChild( "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()); @@ -545,7 +545,7 @@ void LLStatusBar::onMouseEnterNearbyMedia() LLView* popup_holder = gViewerWindow->getRootView()->getChildView("popup_holder"); LLRect nearby_media_rect = mPanelNearByMedia->getRect(); LLButton* nearby_media_btn = getChild( "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, -- cgit v1.3 From 902548c55cce856633a74fe98f515ad4b1804c05 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 3 Mar 2010 20:58:00 -0800 Subject: nested popups close properly --- indra/newview/llpopupview.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'indra/newview/llpopupview.cpp') diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp index 3494522969..d9e4ebcd3c 100644 --- a/indra/newview/llpopupview.cpp +++ b/indra/newview/llpopupview.cpp @@ -117,8 +117,16 @@ BOOL LLPopupView::handleMouseEvent(boost::function func } } - popup->onTopLost(); - mPopups.erase(popup_it++); + if (close_popups) + { + popup_list_t::iterator cur_popup_it = popup_it++; + mPopups.erase(cur_popup_it); + popup->onTopLost(); + } + else + { + ++popup_it; + } } return FALSE; -- 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/newview/llpopupview.cpp') 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 eee50d1401ff7dfcb9c9fdc2c6e61e6d6281f5e2 Mon Sep 17 00:00:00 2001 From: Monroe Linden Date: Fri, 5 Mar 2010 18:11:55 -0800 Subject: Fix for a crash on startup/shutdown introduced in the tip of viewer-2-0 very recently. list.erase(list.find()) is not safe, because erasing list.end() is undefined. Check to make sure the find succeeded before doing the erase. Reviewed by Richard at http://codereview.lindenlab.com/341001 --- indra/newview/llpopupview.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'indra/newview/llpopupview.cpp') diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp index 590a45c96c..1668a91eed 100644 --- a/indra/newview/llpopupview.cpp +++ b/indra/newview/llpopupview.cpp @@ -207,7 +207,11 @@ void LLPopupView::addPopup(LLView* popup) { if (popup) { - mPopups.erase(std::find(mPopups.begin(), mPopups.end(), popup->getHandle())); + 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()); } } @@ -220,7 +224,11 @@ void LLPopupView::removePopup(LLView* popup) { gFocusMgr.setKeyboardFocus(NULL); } - mPopups.erase(std::find(mPopups.begin(), mPopups.end(), popup->getHandle())); + popup_list_t::iterator iter = std::find(mPopups.begin(), mPopups.end(), popup->getHandle()); + if(iter != mPopups.end()) + { + mPopups.erase(iter); + } popup->onTopLost(); } } -- cgit v1.3 From 6b177278802b3b6402e9b7d012e571e6b5171cd1 Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Mon, 8 Mar 2010 12:53:12 -0800 Subject: EXT-6256 - Viewer 2 - Search field set the focus out of the field when user type 'ne' or 'na' or some other letters combinations reviewed by Leyla --- indra/newview/llpopupview.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'indra/newview/llpopupview.cpp') diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp index 1668a91eed..d8ad59c90c 100644 --- a/indra/newview/llpopupview.cpp +++ b/indra/newview/llpopupview.cpp @@ -220,10 +220,6 @@ 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()) { -- cgit v1.3