WIP - replace top ctrl with LLPopupView

master
Richard Linden 2010-03-03 19:37:41 -08:00
parent c3c04adaa5
commit 69f9c0bcf9
15 changed files with 102 additions and 44 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
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();
}
}

View File

@ -231,5 +231,6 @@ private:
commit_callback_t mTextEntryCallback;
commit_callback_t mSelectionCallback;
S32 mLastSelectedIndex;
boost::signals2::connection mTopLostSignalConnection;
};
#endif

View File

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

View File

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

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;

View File

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

View File

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

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

View File

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

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

@ -100,7 +100,7 @@ BOOL LLPopupView::handleMouseEvent(boost::function<BOOL(LLView*, S32, S32)> 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();
}

View File

@ -56,9 +56,11 @@ public:
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);
typedef std::list<LLHandle<LLView> > popup_list_t;
popup_list_t mPopups;
};
#endif //LL_LLROOTVIEW_H

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

View File

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