WIP - replace top ctrl with LLPopupView
parent
c3c04adaa5
commit
69f9c0bcf9
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -231,5 +231,6 @@ private:
|
|||
commit_callback_t mTextEntryCallback;
|
||||
commit_callback_t mSelectionCallback;
|
||||
S32 mLastSelectedIndex;
|
||||
boost::signals2::connection mTopLostSignalConnection;
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
Loading…
Reference in New Issue