summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeslie Linden <leslie@lindenlab.com>2011-10-25 14:14:46 -0700
committerLeslie Linden <leslie@lindenlab.com>2011-10-25 14:14:46 -0700
commit8448e3b86e9ed94a29a6d1e0bdc8b8f78ff84091 (patch)
treea27fb7b097797e0f8be95f5af526b6313dcdb359
parent8e4c3dc14f3c5e8220f7b88bceaa5d1ccbb0a2f0 (diff)
EXP-1398 FIX -- Viewer Crash when moving Speak button from bottom toolbar to side toolbar with call request dialog active on Mac
* Added "on button removed" callback for toolbars. * Changed docking on incoming and outgoing call floaters to be undocked when "speak" button removed. Reviewed by Leyla.
-rw-r--r--indra/llui/lltoolbar.cpp46
-rw-r--r--indra/llui/lltoolbar.h5
-rw-r--r--indra/newview/llimview.cpp52
-rw-r--r--indra/newview/llimview.h6
-rw-r--r--indra/newview/lltoolbarview.cpp84
-rw-r--r--indra/newview/lltoolbarview.h1
6 files changed, 162 insertions, 32 deletions
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 97dc1e3316..ea11750e38 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -114,6 +114,8 @@ LLToolBar::LLToolBar(const LLToolBar::Params& p)
mHandleDropCallback(NULL),
mButtonAddSignal(NULL),
mButtonEnterSignal(NULL),
+ mButtonLeaveSignal(NULL),
+ mButtonRemoveSignal(NULL),
mDragAndDropTarget(false)
{
mButtonParams[LLToolBarEnums::BTNTYPE_ICONS_WITH_TEXT] = p.button_icon_and_text;
@@ -125,6 +127,8 @@ LLToolBar::~LLToolBar()
delete mPopupMenuHandle.get();
delete mButtonAddSignal;
delete mButtonEnterSignal;
+ delete mButtonLeaveSignal;
+ delete mButtonRemoveSignal;
}
void LLToolBar::createContextMenu()
@@ -272,6 +276,11 @@ int LLToolBar::removeCommand(const LLCommandId& commandId)
++rank;
}
+ if (mButtonRemoveSignal)
+ {
+ (*mButtonRemoveSignal)(*it_button);
+ }
+
// Delete the button and erase the command and button records
delete (*it_button);
mButtonCommands.erase(it_command);
@@ -922,16 +931,34 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)
return button;
}
+boost::signals2::connection connectSignal(LLToolBar::button_signal_t*& signal, const LLToolBar::button_signal_t::slot_type& cb)
+{
+ if (!signal)
+ {
+ signal = new LLToolBar::button_signal_t();
+ }
+
+ return signal->connect(cb);
+}
+
boost::signals2::connection LLToolBar::setButtonAddCallback(const button_signal_t::slot_type& cb)
{
- if (!mButtonAddSignal) mButtonAddSignal = new button_signal_t();
- return mButtonAddSignal->connect(cb);
+ return connectSignal(mButtonAddSignal, cb);
}
boost::signals2::connection LLToolBar::setButtonEnterCallback(const button_signal_t::slot_type& cb)
{
- if (!mButtonEnterSignal) mButtonEnterSignal = new button_signal_t();
- return mButtonEnterSignal->connect(cb);
+ return connectSignal(mButtonEnterSignal, cb);
+}
+
+boost::signals2::connection LLToolBar::setButtonLeaveCallback(const button_signal_t::slot_type& cb)
+{
+ return connectSignal(mButtonLeaveSignal, cb);
+}
+
+boost::signals2::connection LLToolBar::setButtonRemoveCallback(const button_signal_t::slot_type& cb)
+{
+ return connectSignal(mButtonRemoveSignal, cb);
}
BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
@@ -1067,6 +1094,17 @@ void LLToolBarButton::onMouseEnter(S32 x, S32 y, MASK mask)
}
}
+void LLToolBarButton::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ LLButton::onMouseLeave(x, y, mask);
+
+ LLToolBar* parent_toolbar = getParentByType<LLToolBar>();
+ if (parent_toolbar && parent_toolbar->mButtonLeaveSignal)
+ {
+ (*(parent_toolbar->mButtonLeaveSignal))(this);
+ }
+}
+
void LLToolBarButton::onMouseCaptureLost()
{
mIsDragged = false;
diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h
index 7ceb75aeed..f10f39adc3 100644
--- a/indra/llui/lltoolbar.h
+++ b/indra/llui/lltoolbar.h
@@ -71,6 +71,7 @@ public:
void setHandleDragCallback(tool_handledrag_callback_t cb) { mHandleDragItemCallback = cb; }
void onMouseEnter(S32 x, S32 y, MASK mask);
+ void onMouseLeave(S32 x, S32 y, MASK mask);
void onMouseCaptureLost();
void onCommit();
@@ -202,6 +203,8 @@ public:
typedef boost::signals2::signal<void (LLView* button)> button_signal_t;
boost::signals2::connection setButtonAddCallback(const button_signal_t::slot_type& cb);
boost::signals2::connection setButtonEnterCallback(const button_signal_t::slot_type& cb);
+ boost::signals2::connection setButtonLeaveCallback(const button_signal_t::slot_type& cb);
+ boost::signals2::connection setButtonRemoveCallback(const button_signal_t::slot_type& cb);
void setTooltipButtonSuffix(const std::string& suffix) { mButtonTooltipSuffix = suffix; }
@@ -269,6 +272,8 @@ private:
button_signal_t* mButtonAddSignal;
button_signal_t* mButtonEnterSignal;
+ button_signal_t* mButtonLeaveSignal;
+ button_signal_t* mButtonRemoveSignal;
std::string mButtonTooltipSuffix;
};
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index c751394455..ed4bb727cd 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -1679,16 +1679,44 @@ BOOL LLCallDialog::postBuild()
{
if (!LLDockableFloater::postBuild() || !gToolBarView)
return FALSE;
+
+ dockToToolbarButton("speak");
+
+ return TRUE;
+}
- LLView *anchor_panel = gToolBarView->findChildView("speak");
- LLDockControl::DocAt dock_pos = getDockControlPos();
- setDockControl(new LLDockControl(anchor_panel, this, getDockTongue(dock_pos), dock_pos));
+void LLCallDialog::dockToToolbarButton(const std::string& toolbarButtonName)
+{
+ LLDockControl::DocAt dock_pos = getDockControlPos(toolbarButtonName);
+ LLView *anchor_panel = gToolBarView->findChildView(toolbarButtonName);
setUseTongue(anchor_panel);
- return TRUE;
+ setDockControl(new LLDockControl(anchor_panel, this, getDockTongue(dock_pos), dock_pos));
}
+LLDockControl::DocAt LLCallDialog::getDockControlPos(const std::string& toolbarButtonName)
+{
+ LLCommandId command_id(toolbarButtonName);
+ S32 toolbar_loc = gToolBarView->hasCommand(command_id);
+
+ LLDockControl::DocAt doc_at = LLDockControl::TOP;
+
+ switch (toolbar_loc)
+ {
+ case LLToolBarView::TOOLBAR_LEFT:
+ doc_at = LLDockControl::RIGHT;
+ break;
+
+ case LLToolBarView::TOOLBAR_RIGHT:
+ doc_at = LLDockControl::LEFT;
+ break;
+ }
+
+ return doc_at;
+}
+
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLOutgoingCallDialog
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1752,22 +1780,6 @@ void LLCallDialog::setIcon(const LLSD& session_id, const LLSD& participant_id)
}
}
-LLDockControl::DocAt LLCallDialog::getDockControlPos()
-{
- LLToolBar* tool_bar = NULL;
-
- if((tool_bar = gToolBarView->getChild<LLToolBar>("toolbar_left")) && tool_bar->hasChild("speak", true))
- {
- return LLDockControl::RIGHT; // Speak button in the left toolbar so the call floater should be to the right of the speak button
- }
- else if((tool_bar = gToolBarView->getChild<LLToolBar>("toolbar_right")) && tool_bar->hasChild("speak", true))
- {
- return LLDockControl::LEFT; // Speak button in the right toolbar so the call floater should be to the left of the speak button
- }
-
- return LLDockControl::TOP;
-}
-
bool LLCallDialog::lifetimeHasExpired()
{
if (mLifetimeTimer.getStarted())
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 33c7ae9e54..b1be26a169 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -495,10 +495,12 @@ public:
virtual BOOL postBuild();
+ void dockToToolbarButton(const std::string& toolbarButtonName);
+
// check timer state
/*virtual*/ void draw();
/*virtual*/ void onOpen(const LLSD& key);
-
+
protected:
// lifetime timer for a notification
LLTimer mLifetimeTimer;
@@ -521,7 +523,7 @@ protected:
LLSD mPayload;
private:
- LLDockControl::DocAt getDockControlPos();
+ LLDockControl::DocAt getDockControlPos(const std::string& toolbarButtonName);
};
class LLIncomingCallDialog : public LLCallDialog
diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
index 8f4f7d405f..ed1dfbb8cd 100644
--- a/indra/newview/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -30,13 +30,16 @@
#include "lltoolbarview.h"
#include "llappviewer.h"
+#include "llbutton.h"
+#include "llclipboard.h"
#include "lldir.h"
-#include "llxmlnode.h"
+#include "lldockablefloater.h"
+#include "lldockcontrol.h"
+#include "llimview.h"
+#include "lltransientfloatermgr.h"
#include "lltoolbar.h"
-#include "llbutton.h"
#include "lltooldraganddrop.h"
-#include "lltransientfloatermgr.h"
-#include "llclipboard.h"
+#include "llxmlnode.h"
#include "llagent.h" // HACK for destinations guide on startup
#include "llfloaterreg.h" // HACK for destinations guide on startup
@@ -102,6 +105,7 @@ BOOL LLToolBarView::postBuild()
mToolbars[i]->setHandleDragCallback(boost::bind(LLToolBarView::handleDragTool,_1,_2,_3,_4));
mToolbars[i]->setHandleDropCallback(boost::bind(LLToolBarView::handleDropTool,_1,_2,_3,_4));
mToolbars[i]->setButtonAddCallback(boost::bind(LLToolBarView::onToolBarButtonAdded,_1));
+ mToolbars[i]->setButtonRemoveCallback(boost::bind(LLToolBarView::onToolBarButtonRemoved,_1));
}
LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&handleLoginToolbarSetup));
@@ -391,13 +395,44 @@ void LLToolBarView::addToToolset(command_id_list_t& command_list, Toolbar& toolb
void LLToolBarView::onToolBarButtonAdded(LLView* button)
{
- if (button && button->getName() == "speak")
+ llassert(button);
+
+ if (button->getName() == "speak")
{
// Add the "Speak" button as a control view in LLTransientFloaterMgr
// to prevent hiding the transient IM floater upon pressing "Speak".
LLTransientFloaterMgr::getInstance()->addControlView(button);
+
+ // Redock incoming and/or outgoing call windows, if applicable
+
+ LLFloater* incoming_floater = LLFloaterReg::getLastFloaterInGroup("incoming_call");
+ LLFloater* outgoing_floater = LLFloaterReg::getLastFloaterInGroup("outgoing_call");
+
+ if (incoming_floater && incoming_floater->isShown())
+ {
+ LLCallDialog* incoming = dynamic_cast<LLCallDialog *>(incoming_floater);
+ llassert(incoming);
+
+ LLDockControl* dock_control = incoming->getDockControl();
+ if (dock_control->getDock() == NULL)
+ {
+ incoming->dockToToolbarButton("speak");
+ }
+ }
+
+ if (outgoing_floater && outgoing_floater->isShown())
+ {
+ LLCallDialog* outgoing = dynamic_cast<LLCallDialog *>(outgoing_floater);
+ llassert(outgoing);
+
+ LLDockControl* dock_control = outgoing->getDockControl();
+ if (dock_control->getDock() == NULL)
+ {
+ outgoing->dockToToolbarButton("speak");
+ }
+ }
}
- else if (button && button->getName() == "voice")
+ else if (button->getName() == "voice")
{
// Add the "Voice controls" button as a control view in LLTransientFloaterMgr
// to prevent hiding the transient IM floater upon pressing "Voice controls".
@@ -405,6 +440,43 @@ void LLToolBarView::onToolBarButtonAdded(LLView* button)
}
}
+void LLToolBarView::onToolBarButtonRemoved(LLView* button)
+{
+ llassert(button);
+
+ if (button->getName() == "speak")
+ {
+ LLTransientFloaterMgr::getInstance()->removeControlView(button);
+
+ // Undock incoming and/or outgoing call windows
+
+ LLFloater* incoming_floater = LLFloaterReg::getLastFloaterInGroup("incoming_call");
+ LLFloater* outgoing_floater = LLFloaterReg::getLastFloaterInGroup("outgoing_call");
+
+ if (incoming_floater && incoming_floater->isShown())
+ {
+ LLDockableFloater* incoming = dynamic_cast<LLDockableFloater *>(incoming_floater);
+ llassert(incoming);
+
+ LLDockControl* dock_control = incoming->getDockControl();
+ dock_control->setDock(NULL);
+ }
+
+ if (outgoing_floater && outgoing_floater->isShown())
+ {
+ LLDockableFloater* outgoing = dynamic_cast<LLDockableFloater *>(outgoing_floater);
+ llassert(outgoing);
+
+ LLDockControl* dock_control = outgoing->getDockControl();
+ dock_control->setDock(NULL);
+ }
+ }
+ else if (button->getName() == "voice")
+ {
+ LLTransientFloaterMgr::getInstance()->removeControlView(button);
+ }
+}
+
void LLToolBarView::draw()
{
LLRect toolbar_rects[TOOLBAR_COUNT];
diff --git a/indra/newview/lltoolbarview.h b/indra/newview/lltoolbarview.h
index 3dc8954abe..4307d10258 100644
--- a/indra/newview/lltoolbarview.h
+++ b/indra/newview/lltoolbarview.h
@@ -117,6 +117,7 @@ private:
void addToToolset(command_id_list_t& command_list, Toolbar& toolbar) const;
static void onToolBarButtonAdded(LLView* button);
+ static void onToolBarButtonRemoved(LLView* button);
// Pointers to the toolbars handled by the toolbar view
LLToolBar* mToolbars[TOOLBAR_COUNT];