master
Richard Linden 2010-03-05 14:46:00 -08:00
commit 931ff555bd
28 changed files with 534 additions and 191 deletions

View File

@ -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();
}
}

View File

@ -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.

View File

@ -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 ) )
{

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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();
}

View File

@ -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)

View File

@ -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;
};

View File

@ -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

View File

@ -347,6 +347,7 @@ set(viewer_SOURCE_FILES
llpatchvertexarray.cpp
llplacesinventorybridge.cpp
llplacesinventorypanel.cpp
llpopupview.cpp
llpolymesh.cpp
llpolymorph.cpp
llpreview.cpp
@ -844,6 +845,7 @@ set(viewer_HEADER_FILES
llplacesinventorypanel.h
llpolymesh.h
llpolymorph.h
llpopupview.h
llpreview.h
llpreviewanim.h
llpreviewgesture.h

View File

@ -703,9 +703,9 @@ bool LLAppViewer::init()
settings_map["account"] = &gSavedPerAccountSettings;
LLUI::initClass(settings_map,
LLUIImageList::getInstance(),
ui_audio_callback,
&LLUI::sGLScaleFactor);
LLUIImageList::getInstance(),
ui_audio_callback,
&LLUI::sGLScaleFactor);
// Setup paths and LLTrans after LLUI::initClass has been called
LLUI::setupPaths();

View File

@ -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()

View File

@ -144,6 +144,7 @@ public:
*/
/*virtual*/ void onTopLost();
/**
* Draws text box, collapses text box if its expanded and its parent's position changed
*/

View File

@ -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>();

View File

@ -82,6 +82,8 @@ LLPanelNearByMedia::LLPanelNearByMedia()
mParcelMediaItem(NULL),
mParcelAudioItem(NULL)
{
mHoverTimer.stop();
mParcelAudioAutoStart = gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
gSavedSettings.getBOOL("MediaTentativeAutoPlay");
@ -187,34 +189,26 @@ 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 )
{
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)

View File

@ -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);

View File

@ -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)

View File

@ -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:

View File

@ -0,0 +1,242 @@
/**
* @file llpopupview.cpp
* @brief Holds transient popups
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2010, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llpopupview.h"
static LLRegisterPanelClassWrapper<LLPopupView> r("popup_holder");
bool view_visible_and_enabled(LLView* viewp)
{
return viewp->getVisible() && viewp->getEnabled();
}
bool view_visible(LLView* viewp)
{
return viewp->getVisible();
}
LLPopupView::LLPopupView()
{
// register ourself as handler of UI popups
LLUI::setPopupFuncs(boost::bind(&LLPopupView::addPopup, this, _1), boost::bind(&LLPopupView::removePopup, this, _1), boost::bind(&LLPopupView::clearPopups, this));
}
LLPopupView::~LLPopupView()
{
// set empty callback function so we can't handle popups anymore
LLUI::setPopupFuncs(LLUI::add_popup_t(), LLUI::remove_popup_t(), LLUI::clear_popups_t());
}
void LLPopupView::draw()
{
S32 screen_x, screen_y;
// remove dead popups
for (popup_list_t::iterator popup_it = mPopups.begin();
popup_it != mPopups.end();)
{
if (!popup_it->get())
{
mPopups.erase(popup_it++);
}
else
{
popup_it++;
}
}
// draw in reverse order (most recent is on top)
for (popup_list_t::reverse_iterator popup_it = mPopups.rbegin();
popup_it != mPopups.rend();)
{
LLView* popup = popup_it->get();
if (popup->getVisible())
{
popup->localPointToScreen(0, 0, &screen_x, &screen_y);
LLUI::pushMatrix();
{
LLUI::translate( (F32) screen_x, (F32) screen_y, 0.f);
popup->draw();
}
LLUI::popMatrix();
}
++popup_it;
}
LLPanel::draw();
}
BOOL LLPopupView::handleMouseEvent(boost::function<BOOL(LLView*, S32, S32)> func,
boost::function<bool(LLView*)> predicate,
S32 x, S32 y,
bool close_popups)
{
for (popup_list_t::iterator popup_it = mPopups.begin();
popup_it != mPopups.end();)
{
LLView* popup = popup_it->get();
if (!popup
|| !predicate(popup))
{
++popup_it;
continue;
}
S32 popup_x, popup_y;
if (localPointToOtherView(x, y, &popup_x, &popup_y, popup)
&& popup->pointInView(popup_x, popup_y))
{
if (func(popup, popup_x, popup_y))
{
return TRUE;
}
}
if (close_popups)
{
popup_list_t::iterator cur_popup_it = popup_it++;
mPopups.erase(cur_popup_it);
popup->onTopLost();
}
else
{
++popup_it;
}
}
return FALSE;
}
BOOL LLPopupView::handleMouseDown(S32 x, S32 y, MASK mask)
{
if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true))
{
return FALSE;
}
return TRUE;
}
BOOL LLPopupView::handleMouseUp(S32 x, S32 y, MASK mask)
{
return handleMouseEvent(boost::bind(&LLMouseHandler::handleMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
}
BOOL LLPopupView::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
{
if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleMiddleMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true))
{
return FALSE;
}
return TRUE;
}
BOOL LLPopupView::handleMiddleMouseUp(S32 x, S32 y, MASK mask)
{
return handleMouseEvent(boost::bind(&LLMouseHandler::handleMiddleMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
}
BOOL LLPopupView::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleRightMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true))
{
return FALSE;
}
return TRUE;
}
BOOL LLPopupView::handleRightMouseUp(S32 x, S32 y, MASK mask)
{
return handleMouseEvent(boost::bind(&LLMouseHandler::handleRightMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
}
BOOL LLPopupView::handleDoubleClick(S32 x, S32 y, MASK mask)
{
return handleMouseEvent(boost::bind(&LLMouseHandler::handleDoubleClick, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
}
BOOL LLPopupView::handleHover(S32 x, S32 y, MASK mask)
{
return handleMouseEvent(boost::bind(&LLMouseHandler::handleHover, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
}
BOOL LLPopupView::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
return handleMouseEvent(boost::bind(&LLMouseHandler::handleScrollWheel, _1, _2, _3, clicks), view_visible_and_enabled, x, y, false);
}
BOOL LLPopupView::handleToolTip(S32 x, S32 y, MASK mask)
{
return handleMouseEvent(boost::bind(&LLMouseHandler::handleToolTip, _1, _2, _3, mask), view_visible, x, y, false);
}
void LLPopupView::addPopup(LLView* popup)
{
if (popup)
{
mPopups.erase(std::find(mPopups.begin(), mPopups.end(), popup->getHandle()));
mPopups.push_front(popup->getHandle());
}
}
void LLPopupView::removePopup(LLView* popup)
{
if (popup)
{
if (gFocusMgr.childHasKeyboardFocus(popup))
{
gFocusMgr.setKeyboardFocus(NULL);
}
mPopups.erase(std::find(mPopups.begin(), mPopups.end(), popup->getHandle()));
popup->onTopLost();
}
}
void LLPopupView::clearPopups()
{
for (popup_list_t::iterator popup_it = mPopups.begin();
popup_it != mPopups.end();)
{
LLView* popup = popup_it->get();
popup_list_t::iterator cur_popup_it = popup_it;
++popup_it;
mPopups.erase(cur_popup_it);
popup->onTopLost();
}
}

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
mPanelNearByMedia = new LLPanelNearByMedia();
popup_holder->addChild(mPanelNearByMedia);
gViewerWindow->getRootView()->addMouseDownCallback(boost::bind(&LLStatusBar::onClickScreen, this, _1, _2));
mPanelNearByMedia->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
mPanelNearByMedia->setVisible(FALSE);
addChild(mPanelVolumePulldown);
mPanelVolumePulldown->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
mPanelVolumePulldown->setVisible(FALSE);
mPanelNearByMedia = new LLPanelNearByMedia();
addChild(mPanelNearByMedia);
mPanelNearByMedia->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
mPanelNearByMedia->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)));

View File

@ -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)

View File

@ -690,23 +690,23 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK
}
// Topmost view gets a chance before the hierarchy
LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
if (top_ctrl)
{
S32 local_x, local_y;
top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
if (top_ctrl->pointInView(local_x, local_y))
{
return top_ctrl->handleAnyMouseClick(local_x, local_y, mask, clicktype, down) ;
}
else
{
if (down)
{
gFocusMgr.setTopCtrl(NULL);
}
}
}
//LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
//if (top_ctrl)
//{
// S32 local_x, local_y;
// top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
// if (top_ctrl->pointInView(local_x, local_y))
// {
// return top_ctrl->handleAnyMouseClick(local_x, local_y, mask, clicktype, down) ;
// }
// else
// {
// if (down)
// {
// gFocusMgr.setTopCtrl(NULL);
// }
// }
//}
// Give the UI views a chance to process the click
if( mRootView->handleAnyMouseClick(x, y, mask, clicktype, down) )
@ -1552,11 +1552,13 @@ void LLViewerWindow::initBase()
mWorldViewPlaceholder = main_view->getChildView("world_view_rect")->getHandle();
mNonSideTrayView = main_view->getChildView("non_side_tray_view")->getHandle();
mFloaterViewHolder = main_view->getChildView("floater_view_holder")->getHandle();
mPopupView = main_view->getChild<LLPopupView>("popup_holder");
// Constrain floaters to inside the menu and status bar regions.
gFloaterView = main_view->getChild<LLFloaterView>("Floater View");
gSnapshotFloaterView = main_view->getChild<LLSnapshotFloaterView>("Snapshot Floater View");
// Console
llassert( !gConsole );
LLConsole::Params cp;
@ -2426,6 +2428,30 @@ void LLViewerWindow::handleScrollWheel(S32 clicks)
return;
}
void LLViewerWindow::addPopup(LLView* popup)
{
if (mPopupView)
{
mPopupView->addPopup(popup);
}
}
void LLViewerWindow::removePopup(LLView* popup)
{
if (mPopupView)
{
mPopupView->removePopup(popup);
}
}
void LLViewerWindow::clearPopups()
{
if (mPopupView)
{
mPopupView->clearPopups();
}
}
void LLViewerWindow::moveCursorToCenter()
{
if (! gSavedSettings.getBOOL("DisableMouseWarp"))
@ -2554,6 +2580,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))

View File

@ -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();

View File

@ -156,18 +156,19 @@
name="notify_container"
tab_group="-2"
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"/>
<panel top="0"
follows="all"
height="768"
mouse_opaque="false"
name="popup_holder"
width="1024"/>
<snapshot_floater_view enabled="false"
follows="all"
height="768"