summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llmath/lloctree.h2
-rw-r--r--indra/llui/lldockablefloater.cpp15
-rw-r--r--indra/llui/lldockablefloater.h4
-rw-r--r--indra/llui/lldockcontrol.cpp62
-rw-r--r--indra/llui/lldockcontrol.h4
-rw-r--r--indra/llui/llfloater.cpp4
-rw-r--r--indra/llui/lltoolbar.cpp122
-rw-r--r--indra/llui/lltoolbar.h23
-rw-r--r--indra/newview/app_settings/settings.xml4
-rw-r--r--indra/newview/app_settings/settings_per_account.xml11
-rw-r--r--indra/newview/llfavoritesbar.cpp129
-rw-r--r--indra/newview/llfavoritesbar.h2
-rw-r--r--indra/newview/llfloatertoybox.cpp30
-rw-r--r--indra/newview/llfloatertoybox.h2
-rw-r--r--indra/newview/llimfloatercontainer.cpp3
-rw-r--r--indra/newview/llimfloatercontainer.h2
-rw-r--r--indra/newview/llimview.cpp37
-rw-r--r--indra/newview/llimview.h9
-rw-r--r--indra/newview/llinventorymodel.cpp50
-rw-r--r--indra/newview/llinventorymodel.h11
-rw-r--r--indra/newview/llnearbychatbar.cpp18
-rw-r--r--indra/newview/llnearbychatbar.h1
-rw-r--r--indra/newview/llnearbychathandler.cpp3
-rw-r--r--indra/newview/llpanelmaininventory.cpp2
-rw-r--r--indra/newview/llsyswellwindow.cpp7
-rw-r--r--indra/newview/lltoolbarview.cpp362
-rw-r--r--indra/newview/lltoolbarview.h39
-rw-r--r--indra/newview/lltransientfloatermgr.cpp43
-rw-r--r--indra/newview/lltransientfloatermgr.h9
-rw-r--r--indra/newview/llviewermenu.cpp5
-rw-r--r--indra/newview/skins/default/textures/windows/Flyout_Left.pngbin0 -> 271 bytes
-rw-r--r--indra/newview/skins/default/textures/windows/Flyout_Right.pngbin0 -> 280 bytes
-rw-r--r--indra/newview/skins/default/xui/en/floater_chat_bar.xml97
-rw-r--r--indra/newview/skins/default/xui/en/floater_outgoing_call.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_toybox.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_voice_controls.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_toolbars.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml11
-rw-r--r--indra/newview/skins/default/xui/en/panel_status_bar.xml7
-rw-r--r--indra/newview/skins/default/xui/en/panel_topinfo_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml6
-rw-r--r--indra/newview/skins/default/xui/en/widgets/toolbar.xml4
42 files changed, 831 insertions, 318 deletions
diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h
index e5ca47da69..3c1ae45d68 100644
--- a/indra/llmath/lloctree.h
+++ b/indra/llmath/lloctree.h
@@ -681,7 +681,7 @@ public:
if (lt != 0x7)
{
- OCT_ERRS << "!!! ELEMENT EXCEEDS RANGE OF SPATIAL PARTITION !!!" << llendl;
+ //OCT_ERRS << "!!! ELEMENT EXCEEDS RANGE OF SPATIAL PARTITION !!!" << llendl;
return false;
}
diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp
index aea58be12a..0fcd937361 100644
--- a/indra/llui/lldockablefloater.cpp
+++ b/indra/llui/lldockablefloater.cpp
@@ -239,8 +239,21 @@ void LLDockableFloater::setDockControl(LLDockControl* dockControl)
setDocked(isDocked());
}
-const LLUIImagePtr& LLDockableFloater::getDockTongue()
+const LLUIImagePtr& LLDockableFloater::getDockTongue(LLDockControl::DocAt dock_side)
{
+ switch(dock_side)
+ {
+ case LLDockControl::LEFT:
+ mDockTongue = LLUI::getUIImage("windows/Flyout_Left.png");
+ break;
+ case LLDockControl::RIGHT:
+ mDockTongue = LLUI::getUIImage("windows/Flyout_Right.png");
+ break;
+ default:
+ mDockTongue = LLUI::getUIImage("windows/Flyout_Pointer.png");
+ break;
+ }
+
return mDockTongue;
}
diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h
index 8deb6c1159..89c9852f4a 100644
--- a/indra/llui/lldockablefloater.h
+++ b/indra/llui/lldockablefloater.h
@@ -113,6 +113,8 @@ public:
bool getUniqueDocking() { return mUniqueDocking; }
bool getUseTongue() { return mUseTongue; }
+
+ void setUseTongue(bool use_tongue) { mUseTongue = use_tongue;}
private:
/**
* Provides unique of dockable floater.
@@ -122,7 +124,7 @@ private:
protected:
void setDockControl(LLDockControl* dockControl);
- const LLUIImagePtr& getDockTongue();
+ const LLUIImagePtr& getDockTongue(LLDockControl::DocAt dock_side = LLDockControl::TOP);
// Checks if docking should be forced.
// It may be useful e.g. if floater created in mouselook mode (see EXT-5609)
diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index 6397bbd0de..af39e41fa6 100644
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -100,12 +100,16 @@ void LLDockControl::repositionDockable()
if (!mDockWidget) return;
LLRect dockRect = mDockWidget->calcScreenRect();
LLRect rootRect;
+ LLRect floater_rect = mDockableFloater->calcScreenRect();
mGetAllowedRectCallback(rootRect);
- // recalculate dockable position if dock position changed, dock visibility changed,
- // root view rect changed or recalculation is forced
- if (mPrevDockRect != dockRect || mDockWidgetVisible != isDockVisible()
- || mRootRect != rootRect || mRecalculateDocablePosition)
+ // recalculate dockable position if:
+ if (mPrevDockRect != dockRect //dock position changed
+ || mDockWidgetVisible != isDockVisible() //dock visibility changed
+ || mRootRect != rootRect //root view rect changed
+ || mFloaterRect != floater_rect //floater rect changed
+ || mRecalculateDockablePosition //recalculation is forced
+ )
{
// undock dockable and off() if dock not visible
if (!isDockVisible())
@@ -136,7 +140,8 @@ void LLDockControl::repositionDockable()
mPrevDockRect = dockRect;
mRootRect = rootRect;
- mRecalculateDocablePosition = false;
+ mFloaterRect = floater_rect;
+ mRecalculateDockablePosition = false;
mDockWidgetVisible = isDockVisible();
}
}
@@ -203,21 +208,33 @@ void LLDockControl::moveDockable()
switch (mDockAt)
{
case LEFT:
- x = dockRect.mLeft;
- y = dockRect.mTop + mDockTongue->getHeight() + dockableRect.getHeight();
- // check is dockable inside root view rect
- if (x < rootRect.mLeft)
+
+ x = dockRect.mLeft - dockableRect.getWidth();
+ y = dockRect.getCenterY() + dockableRect.getHeight() / 2;
+
+ if (use_tongue)
{
- x = rootRect.mLeft;
+ x -= mDockTongue->getWidth();
}
- if (x + dockableRect.getWidth() > rootRect.mRight)
+
+ mDockTongueX = dockableRect.mRight;
+ mDockTongueY = dockableRect.getCenterY() - mDockTongue->getHeight() / 2;
+
+ break;
+
+ case RIGHT:
+
+ x = dockRect.mRight;
+ y = dockRect.getCenterY() + dockableRect.getHeight() / 2;
+
+ if (use_tongue)
{
- x = rootRect.mRight - dockableRect.getWidth();
+ x += mDockTongue->getWidth();
}
-
- mDockTongueX = x + dockableRect.getWidth()/2 - mDockTongue->getWidth() / 2;
-
- mDockTongueY = dockRect.mTop;
+
+ mDockTongueX = dockRect.mRight;
+ mDockTongueY = dockableRect.getCenterY() - mDockTongue->getHeight() / 2;
+
break;
case TOP:
@@ -315,13 +332,12 @@ void LLDockControl::moveDockable()
dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
dockableRect.getHeight());
}
+
LLRect localDocableParentRect;
- mDockableFloater->getParent()->screenRectToLocal(dockableRect,
- &localDocableParentRect);
- mDockableFloater->setRect(localDocableParentRect);
- mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
- &mDockTongueX, &mDockTongueY);
+ mDockableFloater->getParent()->screenRectToLocal(dockableRect, &localDocableParentRect);
+ mDockableFloater->setRect(localDocableParentRect);
+ mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY, &mDockTongueX, &mDockTongueY);
}
@@ -330,7 +346,7 @@ void LLDockControl::on()
if (isDockVisible())
{
mEnabled = true;
- mRecalculateDocablePosition = true;
+ mRecalculateDockablePosition = true;
}
}
@@ -341,7 +357,7 @@ void LLDockControl::off()
void LLDockControl::forceRecalculatePosition()
{
- mRecalculateDocablePosition = true;
+ mRecalculateDockablePosition = true;
}
void LLDockControl::drawToungue()
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
index 2e7359245f..c9602011f6 100644
--- a/indra/llui/lldockcontrol.h
+++ b/indra/llui/lldockcontrol.h
@@ -43,6 +43,7 @@ public:
{
TOP,
LEFT,
+ RIGHT,
BOTTOM
};
@@ -79,12 +80,13 @@ private:
private:
get_allowed_rect_callback_t mGetAllowedRectCallback;
bool mEnabled;
- bool mRecalculateDocablePosition;
+ bool mRecalculateDockablePosition;
bool mDockWidgetVisible;
DocAt mDockAt;
LLView* mDockWidget;
LLRect mPrevDockRect;
LLRect mRootRect;
+ LLRect mFloaterRect;
LLFloater* mDockableFloater;
LLUIImagePtr mDockTongue;
S32 mDockTongueX;
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 7100ea13a7..432397d3e9 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -935,7 +935,7 @@ void LLFloater::applyPositioning(LLFloater* other)
case LLFloaterEnums::OPEN_POSITIONING_CASCADE_GROUP:
case LLFloaterEnums::OPEN_POSITIONING_CASCADING:
- if (other != NULL)
+ if (other != NULL && other != this)
{
stackWith(*other);
}
@@ -1070,7 +1070,7 @@ void LLFloater::handleReshape(const LLRect& new_rect, bool by_user)
const LLRect old_rect = getRect();
LLView::handleReshape(new_rect, by_user);
- if (by_user)
+ if (by_user && !isMinimized())
{
storeRectControl();
mOpenPositioning = LLFloaterEnums::OPEN_POSITIONING_NONE;
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 515605200e..287e3e2b41 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -112,6 +112,10 @@ LLToolBar::LLToolBar(const LLToolBar::Params& p)
mStartDragItemCallback(NULL),
mHandleDragItemCallback(NULL),
mHandleDropCallback(NULL),
+ mButtonAddSignal(NULL),
+ mButtonEnterSignal(NULL),
+ mButtonLeaveSignal(NULL),
+ mButtonRemoveSignal(NULL),
mDragAndDropTarget(false)
{
mButtonParams[LLToolBarEnums::BTNTYPE_ICONS_WITH_TEXT] = p.button_icon_and_text;
@@ -121,6 +125,10 @@ LLToolBar::LLToolBar(const LLToolBar::Params& p)
LLToolBar::~LLToolBar()
{
delete mPopupMenuHandle.get();
+ delete mButtonAddSignal;
+ delete mButtonEnterSignal;
+ delete mButtonLeaveSignal;
+ delete mButtonRemoveSignal;
}
void LLToolBar::createContextMenu()
@@ -212,7 +220,6 @@ bool LLToolBar::addCommand(const LLCommandId& commandId, int rank)
mButtonPanel->addChild(button);
mButtonMap.insert(std::make_pair(commandId.uuid(), button));
-
// Insert the command and button in the right place in their respective lists
if ((rank >= mButtonCommands.size()) || (rank == RANK_NONE))
{
@@ -238,6 +245,14 @@ bool LLToolBar::addCommand(const LLCommandId& commandId, int rank)
mNeedsLayout = true;
+ updateLayoutAsNeeded();
+
+
+ if (mButtonAddSignal)
+ {
+ (*mButtonAddSignal)(button);
+ }
+
return true;
}
@@ -264,6 +279,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);
@@ -352,6 +372,23 @@ bool LLToolBar::stopCommandInProgress(const LLCommandId& commandId)
return (command_button != NULL);
}
+bool LLToolBar::flashCommand(const LLCommandId& commandId, bool flash)
+{
+ LLButton * command_button = NULL;
+
+ if (commandId != LLCommandId::null)
+ {
+ command_id_map::iterator it = mButtonMap.find(commandId.uuid());
+ if (it != mButtonMap.end())
+ {
+ command_button = it->second;
+ command_button->setFlashing(flash ? TRUE : FALSE);
+ }
+ }
+
+ return (command_button != NULL);
+}
+
BOOL LLToolBar::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
LLRect button_panel_rect;
@@ -790,6 +827,11 @@ void LLToolBar::createButtons()
{
BOOST_FOREACH(LLToolBarButton* button, mButtons)
{
+ if (mButtonRemoveSignal)
+ {
+ (*mButtonRemoveSignal)(button);
+ }
+
delete button;
}
mButtons.clear();
@@ -801,6 +843,11 @@ void LLToolBar::createButtons()
mButtons.push_back(button);
mButtonPanel->addChild(button);
mButtonMap.insert(std::make_pair(command_id.uuid(), button));
+
+ if (mButtonAddSignal)
+ {
+ (*mButtonAddSignal)(button);
+ }
}
mNeedsLayout = true;
}
@@ -870,8 +917,7 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)
button->setCommitCallback(executeParam);
}
-
-
+ // Set up "is running" query callback
const std::string& isRunningFunction = commandp->isRunningFunctionName();
if (isRunningFunction.length() > 0)
{
@@ -898,6 +944,36 @@ 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)
+{
+ return connectSignal(mButtonAddSignal, cb);
+}
+
+boost::signals2::connection LLToolBar::setButtonEnterCallback(const button_signal_t::slot_type& 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,
EDragAndDropType cargo_type,
void* cargo_data,
@@ -969,8 +1045,6 @@ LLToolBarButton::LLToolBarButton(const Params& p)
mOriginalImageOverlayColor(p.image_overlay_color),
mOriginalImageOverlaySelectedColor(p.image_overlay_selected_color)
{
- mButtonFlashRate = 0.0;
- mButtonFlashCount = 0;
}
LLToolBarButton::~LLToolBarButton()
@@ -1012,6 +1086,7 @@ BOOL LLToolBarButton::handleHover(S32 x, S32 y, MASK mask)
{
handled = LLButton::handleHover(x, y, mask);
}
+
return handled;
}
@@ -1024,6 +1099,23 @@ void LLToolBarButton::onMouseEnter(S32 x, S32 y, MASK mask)
{
mNeedsHighlight = TRUE;
}
+
+ LLToolBar* parent_toolbar = getParentByType<LLToolBar>();
+ if (parent_toolbar && parent_toolbar->mButtonEnterSignal)
+ {
+ (*(parent_toolbar->mButtonEnterSignal))(this);
+ }
+}
+
+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()
@@ -1072,25 +1164,25 @@ void LLToolBarButton::setEnabled(BOOL enabled)
}
}
-
const std::string LLToolBarButton::getToolTip() const
{
std::string tooltip;
+
if (labelIsTruncated() || getCurrentLabel().empty())
{
- return LLTrans::getString(LLCommandManager::instance().getCommand(mId)->labelRef()) + " -- " + LLView::getToolTip();
+ tooltip = LLTrans::getString(LLCommandManager::instance().getCommand(mId)->labelRef()) + " -- " + LLView::getToolTip();
}
else
{
- return LLView::getToolTip();
+ tooltip = LLView::getToolTip();
}
-}
-
-
-
-
-
-
+ LLToolBar* parent_toolbar = getParentByType<LLToolBar>();
+ if (parent_toolbar && parent_toolbar->mButtonTooltipSuffix.length() > 0)
+ {
+ tooltip = tooltip + "\n(" + parent_toolbar->mButtonTooltipSuffix + ")";
+ }
+ return tooltip;
+}
diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h
index e634e57f93..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();
@@ -120,6 +121,8 @@ namespace LLToolBarEnums
SIDE_RIGHT,
SIDE_TOP,
};
+
+ LLLayoutStack::ELayoutOrientation getOrientation(SideType sideType);
}
// NOTE: This needs to occur before Param block declaration for proper compilation.
@@ -142,6 +145,7 @@ namespace LLInitParam
class LLToolBar
: public LLUICtrl
{
+ friend class LLToolBarButton;
public:
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
@@ -187,6 +191,7 @@ public:
bool hasCommand(const LLCommandId& commandId) const;
bool enableCommand(const LLCommandId& commandId, bool enabled);
bool stopCommandInProgress(const LLCommandId& commandId);
+ bool flashCommand(const LLCommandId& commandId, bool flash);
void setStartDragCallback(tool_startdrag_callback_t cb) { mStartDragItemCallback = cb; }
void setHandleDragCallback(tool_handledrag_callback_t cb) { mHandleDragItemCallback = cb; }
@@ -195,6 +200,15 @@ public:
LLToolBarButton* createButton(const LLCommandId& id);
+ 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; }
+
+ LLToolBarEnums::SideType getSideType() const { return mSideType; }
bool hasButtons() const { return !mButtons.empty(); }
bool isModified() const { return mModified; }
@@ -254,7 +268,14 @@ private:
LLToolBarButton::Params mButtonParams[LLToolBarEnums::BTNTYPE_COUNT];
- LLHandle<class LLContextMenu> mPopupMenuHandle;
+ LLHandle<class LLContextMenu> mPopupMenuHandle;
+
+ button_signal_t* mButtonAddSignal;
+ button_signal_t* mButtonEnterSignal;
+ button_signal_t* mButtonLeaveSignal;
+ button_signal_t* mButtonRemoveSignal;
+
+ std::string mButtonTooltipSuffix;
};
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 7cfbba3160..5c0ea2f774 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -13383,7 +13383,7 @@
<key>Comment</key>
<string>Settings that are a applied per session (not saved).</string>
<key>Persist</key>
- <integer>1</integer>
+ <integer>0</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
@@ -13394,7 +13394,7 @@
<key>Comment</key>
<string>User settings that are a applied per session (not saved).</string>
<key>Persist</key>
- <integer>1</integer>
+ <integer>0</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index d8295ddb87..6ed4480cb1 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -33,6 +33,17 @@
<key>Value</key>
<string />
</map>
+ <key>DisplayDestinationsOnInitialRun</key>
+ <map>
+ <key>Comment</key>
+ <string>Display the destinations guide when a user first launches FUI.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>LastInventoryInboxActivity</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 98de418878..6c9058caf1 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -443,17 +443,17 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
{
setLandingTab(dest);
}
- /*
- * the condition dest == NULL can be satisfied not only in the case
- * of dragging to the right from the last tab of the favbar. there is a
- * small gap between each tab. if the user drags something exactly there
- * then mLandingTab will be set to NULL and the dragged item will be pushed
- * to the end of the favorites bar. this is incorrect behavior. that's why
- * we need an additional check which excludes the case described previously
- * making sure that the mouse pointer is beyond the last tab.
- */
- else if (mLastTab && x >= mLastTab->getRect().mRight)
+ else if (mLastTab && (x >= mLastTab->getRect().mRight))
{
+ /*
+ * the condition dest == NULL can be satisfied not only in the case
+ * of dragging to the right from the last tab of the favbar. there is a
+ * small gap between each tab. if the user drags something exactly there
+ * then mLandingTab will be set to NULL and the dragged item will be pushed
+ * to the end of the favorites bar. this is incorrect behavior. that's why
+ * we need an additional check which excludes the case described previously
+ * making sure that the mouse pointer is beyond the last tab.
+ */
setLandingTab(NULL);
}
@@ -467,7 +467,6 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
if (drop)
{
handleExistingFavoriteDragAndDrop(x, y);
- showDragMarker(FALSE);
}
}
else
@@ -490,7 +489,6 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
setLandingTab(NULL);
}
handleNewFavoriteDragAndDrop(item, favorites_id, x, y);
- showDragMarker(FALSE);
}
}
}
@@ -504,20 +502,29 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y)
{
+ // Identify the button hovered and the side to drop
LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(mLandingTab);
+ bool insert_before = true;
+ if (!dest)
+ {
+ insert_before = false;
+ dest = dynamic_cast<LLFavoriteLandmarkButton*>(mLastTab);
+ }
- // there is no need to handle if an item was dragged onto itself
+ // There is no need to handle if an item was dragged onto itself
if (dest && dest->getLandmarkId() == mDragItemId)
{
return;
}
+ // Insert the dragged item in the right place
if (dest)
{
- LLInventoryModel::updateItemsOrder(mItems, mDragItemId, dest->getLandmarkId());
+ LLInventoryModel::updateItemsOrder(mItems, mDragItemId, dest->getLandmarkId(), insert_before);
}
else
{
+ // This can happen when the item list is empty
mItems.push_back(gInventory.getItem(mDragItemId));
}
@@ -534,22 +541,35 @@ void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y)
void LLFavoritesBarCtrl::handleNewFavoriteDragAndDrop(LLInventoryItem *item, const LLUUID& favorites_id, S32 x, S32 y)
{
- LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(mLandingTab);
-
- // there is no need to handle if an item was dragged onto itself
+ // Identify the button hovered and the side to drop
+ LLFavoriteLandmarkButton* dest = NULL;
+ bool insert_before = true;
+ if (!mItems.empty())
+ {
+ dest = dynamic_cast<LLFavoriteLandmarkButton*>(mLandingTab);
+ if (!dest)
+ {
+ insert_before = false;
+ dest = dynamic_cast<LLFavoriteLandmarkButton*>(mLastTab);
+ }
+ }
+
+ // There is no need to handle if an item was dragged onto itself
if (dest && dest->getLandmarkId() == mDragItemId)
{
return;
}
-
+
LLPointer<LLViewerInventoryItem> viewer_item = new LLViewerInventoryItem(item);
+ // Insert the dragged item in the right place
if (dest)
{
- insertBeforeItem(mItems, dest->getLandmarkId(), viewer_item);
+ insertItem(mItems, dest->getLandmarkId(), viewer_item, insert_before);
}
else
{
+ // This can happen when the item list is empty
mItems.push_back(viewer_item);
}
@@ -642,7 +662,7 @@ void LLFavoritesBarCtrl::draw()
{
// mouse pointer hovers over an existing tab
LLRect rect = mLandingTab->getRect();
- mImageDragIndication->draw(rect.mLeft - w/2, rect.getHeight(), w, h);
+ mImageDragIndication->draw(rect.mLeft, rect.getHeight(), w, h);
}
else if (mLastTab)
{
@@ -650,6 +670,8 @@ void LLFavoritesBarCtrl::draw()
LLRect rect = mLastTab->getRect();
mImageDragIndication->draw(rect.mRight, rect.getHeight(), w, h);
}
+ // Once drawn, mark this false so we won't draw it again (unless we hit the favorite bar again)
+ mShowDragMarker = FALSE;
}
}
@@ -721,7 +743,7 @@ void LLFavoritesBarCtrl::updateButtons()
if (first_changed_item_index <= mItems.count())
{
// Rebuild the buttons only
- // child_list_t is a linked list, so safe to erase from the middle if we pre-incrament the iterator
+ // child_list_t is a linked list, so safe to erase from the middle if we pre-increment the iterator
while (child_it != childs->end())
{
@@ -810,9 +832,9 @@ LLButton* LLFavoritesBarCtrl::createButton(const LLPointer<LLViewerInventoryItem
/**
* WORKAROUND:
- * there are some problem with displaying of fonts in buttons.
- * Empty space (or ...) is displaying instead of last symbols, even though the width of the button is enough.
- * Problem will gone, if we stretch out the button. For that reason I have to put additional 20 pixels.
+ * There are some problem with displaying of fonts in buttons.
+ * Empty space or ellipsis might be displayed instead of last symbols, even though the width of the button is enough.
+ * The problem disappears if we pad the button with 20 pixels.
*/
int required_width = mFont->getWidth(item->getName()) + 20;
int width = required_width > def_button_width? def_button_width : required_width;
@@ -840,7 +862,6 @@ LLButton* LLFavoritesBarCtrl::createButton(const LLPointer<LLViewerInventoryItem
fav_btn->setRect(butt_rect);
// change only left and save bottom
fav_btn->setFont(mFont);
- fav_btn->setName(item->getName());
fav_btn->setLabel(item->getName());
fav_btn->setToolTip(item->getName());
fav_btn->setCommitCallback(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID()));
@@ -1298,25 +1319,24 @@ BOOL LLFavoritesBarCtrl::handleHover(S32 x, S32 y, MASK mask)
LLUICtrl* LLFavoritesBarCtrl::findChildByLocalCoords(S32 x, S32 y)
{
- LLUICtrl* ctrl = 0;
- S32 screenX, screenY;
+ LLUICtrl* ctrl = NULL;
const child_list_t* list = getChildList();
- localPointToScreen(x, y, &screenX, &screenY);
-
- // look for a child which contains the point (screenX, screenY) in it's rectangle
for (child_list_const_iter_t i = list->begin(); i != list->end(); ++i)
{
- LLRect rect;
- localRectToScreen((*i)->getRect(), &rect);
-
- if (rect.pointInRect(screenX, screenY))
+ // Look only for children that are favorite buttons
+ if ((*i)->getName() == "favorites_bar_btn")
{
- ctrl = dynamic_cast<LLUICtrl*>(*i);
- break;
+ LLRect rect = (*i)->getRect();
+ // We consider a button hit if the cursor is left of the right side
+ // This makes the hit a bit less finicky than hitting directly on the button itself
+ if (x <= rect.mRight)
+ {
+ ctrl = dynamic_cast<LLUICtrl*>(*i);
+ break;
+ }
}
}
-
return ctrl;
}
@@ -1337,29 +1357,28 @@ BOOL LLFavoritesBarCtrl::needToSaveItemsOrder(const LLInventoryModel::item_array
return result;
}
-LLInventoryModel::item_array_t::iterator LLFavoritesBarCtrl::findItemByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id)
+void LLFavoritesBarCtrl::insertItem(LLInventoryModel::item_array_t& items, const LLUUID& dest_item_id, LLViewerInventoryItem* insertedItem, bool insert_before)
{
- LLInventoryModel::item_array_t::iterator result = items.end();
+ // Get the iterator to the destination item
+ LLInventoryModel::item_array_t::iterator it_dest = LLInventoryModel::findItemIterByUUID(items, dest_item_id);
+ if (it_dest == items.end())
+ return;
- for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
+ // Go to the next element if one wishes to insert after the dest element
+ if (!insert_before)
{
- if ((*i)->getUUID() == id)
- {
- result = i;
- break;
- }
+ ++it_dest;
}
-
- return result;
-}
-
-void LLFavoritesBarCtrl::insertBeforeItem(LLInventoryModel::item_array_t& items, const LLUUID& beforeItemId, LLViewerInventoryItem* insertedItem)
-{
- LLViewerInventoryItem* beforeItem = gInventory.getItem(beforeItemId);
- llassert(beforeItem);
- if (beforeItem)
+
+ // Insert the source item in the right place
+ if (it_dest != items.end())
+ {
+ items.insert(it_dest, insertedItem);
+ }
+ else
{
- items.insert(findItemByUUID(items, beforeItem->getUUID()), insertedItem);
+ // Append to the list if it_dest reached the end
+ items.push_back(insertedItem);
}
}
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 1b11d6196e..2f75b3bb0e 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -130,7 +130,7 @@ private:
* inserts an item identified by insertedItemId BEFORE an item identified by beforeItemId.
* this function assumes that an item identified by insertedItemId doesn't exist in items array.
*/
- void insertBeforeItem(LLInventoryModel::item_array_t& items, const LLUUID& beforeItemId, LLViewerInventoryItem* insertedItem);
+ void insertItem(LLInventoryModel::item_array_t& items, const LLUUID& dest_item_id, LLViewerInventoryItem* insertedItem, bool insert_before);
// finds an item by it's UUID in the items array
LLInventoryModel::item_array_t::iterator findItemByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id);
diff --git a/indra/newview/llfloatertoybox.cpp b/indra/newview/llfloatertoybox.cpp
index 66f644748e..f527937e8f 100644
--- a/indra/newview/llfloatertoybox.cpp
+++ b/indra/newview/llfloatertoybox.cpp
@@ -63,6 +63,7 @@ BOOL LLFloaterToybox::postBuild()
mToolBar->setStartDragCallback(boost::bind(LLToolBarView::startDragTool,_1,_2,_3));
mToolBar->setHandleDragCallback(boost::bind(LLToolBarView::handleDragTool,_1,_2,_3,_4));
mToolBar->setHandleDropCallback(boost::bind(LLToolBarView::handleDropTool,_1,_2,_3,_4));
+ mToolBar->setButtonEnterCallback(boost::bind(&LLFloaterToybox::onToolBarButtonEnter,this,_1));
//
// Sort commands by localized labels so they will appear alphabetized in all languages
@@ -105,8 +106,8 @@ void LLFloaterToybox::draw()
{
const LLCommandId& id = *it;
- const bool commandOnToolbar = gToolBarView->hasCommand(id);
- mToolBar->enableCommand(id, !commandOnToolbar);
+ const bool command_not_present = (gToolBarView->hasCommand(id) == LLToolBarView::TOOLBAR_NONE);
+ mToolBar->enableCommand(id, command_not_present);
}
LLFloater::draw();
@@ -140,5 +141,30 @@ BOOL LLFloaterToybox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
return mToolBar->handleDragAndDrop(local_x, local_y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
}
+void LLFloaterToybox::onToolBarButtonEnter(LLView* button)
+{
+ std::string suffix = "";
+
+ LLCommandId commandId(button->getName());
+ LLCommand* command = LLCommandManager::instance().getCommand(commandId);
+
+ if (command)
+ {
+ S32 command_loc = gToolBarView->hasCommand(commandId);
+
+ switch(command_loc)
+ {
+ case LLToolBarView::TOOLBAR_BOTTOM: suffix = LLTrans::getString("Toolbar_Bottom_Tooltip"); break;
+ case LLToolBarView::TOOLBAR_LEFT: suffix = LLTrans::getString("Toolbar_Left_Tooltip"); break;
+ case LLToolBarView::TOOLBAR_RIGHT: suffix = LLTrans::getString("Toolbar_Right_Tooltip"); break;
+
+ default:
+ break;
+ }
+ }
+
+ mToolBar->setTooltipButtonSuffix(suffix);
+}
+
// eof
diff --git a/indra/newview/llfloatertoybox.h b/indra/newview/llfloatertoybox.h
index 62bf68680d..6f0275b8fe 100644
--- a/indra/newview/llfloatertoybox.h
+++ b/indra/newview/llfloatertoybox.h
@@ -52,6 +52,8 @@ public:
protected:
void onBtnRestoreDefaults();
+ void onToolBarButtonEnter(LLView* button);
+
public:
LLToolBar * mToolBar;
};
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 33cb3a54a7..c8e48b0d42 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -47,12 +47,13 @@ LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
LLIMFloaterContainer::~LLIMFloaterContainer()
{
+ mNewMessageConnection.disconnect();
LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
}
BOOL LLIMFloaterContainer::postBuild()
{
- LLIMModel::instance().mNewMsgSignal.connect(boost::bind(&LLIMFloaterContainer::onNewMessageReceived, this, _1));
+ mNewMessageConnection = LLIMModel::instance().mNewMsgSignal.connect(boost::bind(&LLIMFloaterContainer::onNewMessageReceived, this, _1));
// Do not call base postBuild to not connect to mCloseSignal to not close all floaters via Close button
// mTabContainer will be initialized in LLMultiFloater::addChild()
return TRUE;
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 53dfcd78ff..892ecef48d 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -62,7 +62,7 @@ public:
private:
typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
avatarID_panel_map_t mSessions;
-
+ boost::signals2::connection mNewMessageConnection;
void onNewMessageReceived(const LLSD& data);
};
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 6e9baed5f2..ed4bb727cd 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -1679,13 +1679,44 @@ BOOL LLCallDialog::postBuild()
{
if (!LLDockableFloater::postBuild() || !gToolBarView)
return FALSE;
+
+ dockToToolbarButton("speak");
+
+ return TRUE;
+}
+
+void LLCallDialog::dockToToolbarButton(const std::string& toolbarButtonName)
+{
+ LLDockControl::DocAt dock_pos = getDockControlPos(toolbarButtonName);
+ LLView *anchor_panel = gToolBarView->findChildView(toolbarButtonName);
- LLView *anchor_panel = gToolBarView->findChildView("speak");
- setDockControl(new LLDockControl(anchor_panel, this, getDockTongue(), LLDockControl::TOP));
+ 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
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 93b604d36a..b1be26a169 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -491,14 +491,16 @@ class LLCallDialog : public LLDockableFloater
{
public:
LLCallDialog(const LLSD& payload);
- ~LLCallDialog();
+ virtual ~LLCallDialog();
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;
@@ -519,6 +521,9 @@ protected:
void setIcon(const LLSD& session_id, const LLSD& participant_id);
LLSD mPayload;
+
+private:
+ LLDockControl::DocAt getDockControlPos(const std::string& toolbarButtonName);
};
class LLIncomingCallDialog : public LLCallDialog
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index e86c427ae2..fb02fe0ff7 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -2879,40 +2879,62 @@ BOOL LLInventoryModel::getIsFirstTimeInViewer2()
return sFirstTimeInViewer2;
}
-static LLInventoryModel::item_array_t::iterator find_item_iter_by_uuid(LLInventoryModel::item_array_t& items, const LLUUID& id)
+LLInventoryModel::item_array_t::iterator LLInventoryModel::findItemIterByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id)
{
- LLInventoryModel::item_array_t::iterator result = items.end();
+ LLInventoryModel::item_array_t::iterator curr_item = items.begin();
- for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
+ while (curr_item != items.end())
{
- if ((*i)->getUUID() == id)
+ if ((*curr_item)->getUUID() == id)
{
- result = i;
break;
}
+ ++curr_item;
}
- return result;
+ return curr_item;
}
// static
// * @param[in, out] items - vector with items to be updated. It should be sorted in a right way
// * before calling this method.
// * @param src_item_id - LLUUID of inventory item to be moved in new position
-// * @param dest_item_id - LLUUID of inventory item before which source item should be placed.
-void LLInventoryModel::updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& src_item_id, const LLUUID& dest_item_id)
+// * @param dest_item_id - LLUUID of inventory item before (or after) which source item should
+// * be placed.
+// * @param insert_before - bool indicating if src_item_id should be placed before or after
+// * dest_item_id. Default is true.
+void LLInventoryModel::updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& src_item_id, const LLUUID& dest_item_id, bool insert_before)
{
- LLInventoryModel::item_array_t::iterator it_src = find_item_iter_by_uuid(items, src_item_id);
- LLInventoryModel::item_array_t::iterator it_dest = find_item_iter_by_uuid(items, dest_item_id);
+ LLInventoryModel::item_array_t::iterator it_src = findItemIterByUUID(items, src_item_id);
+ LLInventoryModel::item_array_t::iterator it_dest = findItemIterByUUID(items, dest_item_id);
- if (it_src == items.end() || it_dest == items.end()) return;
+ // If one of the passed UUID is not in the item list, bail out
+ if ((it_src == items.end()) || (it_dest == items.end()))
+ return;
+ // Erase the source element from the list, keep a copy before erasing.
LLViewerInventoryItem* src_item = *it_src;
items.erase(it_src);
- // target iterator can not be valid because the container was changed, so update it.
- it_dest = find_item_iter_by_uuid(items, dest_item_id);
- items.insert(it_dest, src_item);
+ // Note: Target iterator is not valid anymore because the container was changed, so update it.
+ it_dest = findItemIterByUUID(items, dest_item_id);
+
+ // Go to the next element if one wishes to insert after the dest element
+ if (!insert_before)
+ {
+ ++it_dest;
+ }
+
+ // Reinsert the source item in the right place
+ if (it_dest != items.end())
+ {
+ items.insert(it_dest, src_item);
+ }
+ else
+ {
+ // Append to the list if it_dest reached the end
+ items.push_back(src_item);
+ }
}
//* @param[in] items vector of items in order to be saved.
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index e0e81f1006..a0fd455cf3 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -332,11 +332,16 @@ protected:
//--------------------------------------------------------------------
public:
// Changes items order by insertion of the item identified by src_item_id
- // before the item identified by dest_item_id. Both items must exist in items array.
- // Sorting is stored after method is finished. Only src_item_id is moved before dest_item_id.
+ // before (or after) the item identified by dest_item_id. Both items must exist in items array.
+ // Sorting is stored after method is finished. Only src_item_id is moved before (or after) dest_item_id.
+ // The parameter "insert_before" controls on which side of dest_item_id src_item_id gets rensinserted.
static void updateItemsOrder(LLInventoryModel::item_array_t& items,
const LLUUID& src_item_id,
- const LLUUID& dest_item_id);
+ const LLUUID& dest_item_id,
+ bool insert_before = true);
+ // Gets an iterator on an item vector knowing only the item UUID.
+ // Returns end() of the vector if not found.
+ static LLInventoryModel::item_array_t::iterator findItemIterByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id);
// Saves current order of the passed items using inventory item sort field.
// Resets 'items' sort fields and saves them on server.
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index a811332261..4674c85324 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -147,12 +147,12 @@ LLNearbyChatBar* LLNearbyChatBar::getInstance()
void LLNearbyChatBar::showHistory()
{
+ openFloater();
+
if (!getChildView("nearby_chat")->getVisible())
{
onToggleNearbyChatPanel();
}
-
- openFloater();
}
void LLNearbyChatBar::draw()
@@ -379,7 +379,10 @@ void LLNearbyChatBar::onToggleNearbyChatPanel()
if (nearby_chat->getVisible())
{
- mExpandedHeight = getRect().getHeight();
+ if (!isMinimized())
+ {
+ mExpandedHeight = getRect().getHeight();
+ }
setResizeLimits(getMinWidth(), COLLAPSED_HEIGHT);
nearby_chat->setVisible(FALSE);
reshape(getRect().getWidth(), COLLAPSED_HEIGHT);
@@ -396,6 +399,15 @@ void LLNearbyChatBar::onToggleNearbyChatPanel()
}
}
+void LLNearbyChatBar::setMinimized(BOOL b)
+{
+ if (b != LLFloater::isMinimized())
+ {
+ LLFloater::setMinimized(b);
+ getChildView("nearby_chat")->setVisible(!b);
+ }
+}
+
void LLNearbyChatBar::onChatBoxCommit()
{
if (mChatBox->getText().length() > 0)
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
index bc00c1b9fc..e9734899b3 100644
--- a/indra/newview/llnearbychatbar.h
+++ b/indra/newview/llnearbychatbar.h
@@ -60,6 +60,7 @@ public:
static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
void showHistory();
+ /*virtual*/void setMinimized(BOOL b);
protected:
static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index 330a21ef65..c43c95a366 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -568,7 +568,8 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, // WARNING - not
sChatWatcher->post(notification);
- if( chat_bar->getVisible() && nearby_chat->getVisible()
+ if( !chat_bar->isMinimized()
+ && nearby_chat->isInVisibleChain()
|| ( chat_msg.mSourceType == CHAT_SOURCE_AGENT
&& gSavedSettings.getBOOL("UseChatBubbles") )
|| !mChannel->getShowToasts() ) // to prevent toasts in Busy mode
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index d6c407d548..9944b51902 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -111,7 +111,7 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH));
mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLFolderType::FT_LOST_AND_FOUND));
mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLPanelMainInventory::doCreate, this, _2));
- mCommitCallbackRegistrar.add("Inventory.NewWindow", boost::bind(&LLPanelMainInventory::newWindow, this));
+ //mCommitCallbackRegistrar.add("Inventory.NewWindow", boost::bind(&LLPanelMainInventory::newWindow, this));
mCommitCallbackRegistrar.add("Inventory.ShowFilters", boost::bind(&LLPanelMainInventory::toggleFindOptions, this));
mCommitCallbackRegistrar.add("Inventory.ResetFilters", boost::bind(&LLPanelMainInventory::resetFilters, this));
mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLPanelMainInventory::setSortBy, this, _2));
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index ffe864e220..3aa6a3b7e5 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -203,10 +203,9 @@ void LLSysWellWindow::reshapeWindow()
{
new_window_height = MAX_WINDOW_HEIGHT;
}
- S32 newY = curRect.mTop + new_window_height - curRect.getHeight();
- S32 newWidth = curRect.getWidth() < MIN_WINDOW_WIDTH ? MIN_WINDOW_WIDTH
- : curRect.getWidth();
- curRect.setLeftTopAndSize(curRect.mLeft, newY, newWidth, new_window_height);
+ S32 newWidth = curRect.getWidth() < MIN_WINDOW_WIDTH ? MIN_WINDOW_WIDTH : curRect.getWidth();
+
+ curRect.setLeftTopAndSize(curRect.mLeft, curRect.mTop, newWidth, new_window_height);
reshape(curRect.getWidth(), curRect.getHeight(), TRUE);
setRect(curRect);
}
diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
index 5d2cebe031..ed1dfbb8cd 100644
--- a/indra/newview/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -30,12 +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 "llclipboard.h"
+#include "llxmlnode.h"
#include "llagent.h" // HACK for destinations guide on startup
#include "llfloaterreg.h" // HACK for destinations guide on startup
@@ -68,13 +72,14 @@ LLToolBarView::ToolbarSet::ToolbarSet()
LLToolBarView::LLToolBarView(const LLToolBarView::Params& p)
: LLUICtrl(p),
- mToolbarLeft(NULL),
- mToolbarRight(NULL),
- mToolbarBottom(NULL),
mDragStarted(false),
mDragToolbarButton(NULL),
mToolbarsLoaded(false)
{
+ for (S32 i = 0; i < TOOLBAR_COUNT; i++)
+ {
+ mToolbars[i] = NULL;
+ }
}
void LLToolBarView::initFromParams(const LLToolBarView::Params& p)
@@ -90,46 +95,100 @@ LLToolBarView::~LLToolBarView()
BOOL LLToolBarView::postBuild()
{
- mToolbarLeft = getChild<LLToolBar>("toolbar_left");
- mToolbarRight = getChild<LLToolBar>("toolbar_right");
- mToolbarBottom = getChild<LLToolBar>("toolbar_bottom");
+ mToolbars[TOOLBAR_LEFT] = getChild<LLToolBar>("toolbar_left");
+ mToolbars[TOOLBAR_RIGHT] = getChild<LLToolBar>("toolbar_right");
+ mToolbars[TOOLBAR_BOTTOM] = getChild<LLToolBar>("toolbar_bottom");
- mToolbarLeft->setStartDragCallback(boost::bind(LLToolBarView::startDragTool,_1,_2,_3));
- mToolbarLeft->setHandleDragCallback(boost::bind(LLToolBarView::handleDragTool,_1,_2,_3,_4));
- mToolbarLeft->setHandleDropCallback(boost::bind(LLToolBarView::handleDropTool,_1,_2,_3,_4));
-
- mToolbarRight->setStartDragCallback(boost::bind(LLToolBarView::startDragTool,_1,_2,_3));
- mToolbarRight->setHandleDragCallback(boost::bind(LLToolBarView::handleDragTool,_1,_2,_3,_4));
- mToolbarRight->setHandleDropCallback(boost::bind(LLToolBarView::handleDropTool,_1,_2,_3,_4));
-
- mToolbarBottom->setStartDragCallback(boost::bind(LLToolBarView::startDragTool,_1,_2,_3));
- mToolbarBottom->setHandleDragCallback(boost::bind(LLToolBarView::handleDragTool,_1,_2,_3,_4));
- mToolbarBottom->setHandleDropCallback(boost::bind(LLToolBarView::handleDropTool,_1,_2,_3,_4));
+ for (int i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
+ {
+ mToolbars[i]->setStartDragCallback(boost::bind(LLToolBarView::startDragTool,_1,_2,_3));
+ 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));
return TRUE;
}
-bool LLToolBarView::hasCommand(const LLCommandId& commandId) const
+S32 LLToolBarView::hasCommand(const LLCommandId& commandId) const
+{
+ S32 command_location = TOOLBAR_NONE;
+
+ for (S32 loc = TOOLBAR_FIRST; loc <= TOOLBAR_LAST; loc++)
+ {
+ if (mToolbars[loc]->hasCommand(commandId))
+ {
+ command_location = loc;
+ break;
+ }
+ }
+
+ return command_location;
+}
+
+S32 LLToolBarView::addCommand(const LLCommandId& commandId, EToolBarLocation toolbar, int rank)
+{
+ int old_rank;
+ removeCommand(commandId, old_rank);
+
+ S32 command_location = mToolbars[toolbar]->addCommand(commandId, rank);
+
+ return command_location;
+}
+
+S32 LLToolBarView::removeCommand(const LLCommandId& commandId, int& rank)
{
- bool has_command = false;
- if (mToolbarLeft && !has_command)
+ S32 command_location = hasCommand(commandId);
+ rank = LLToolBar::RANK_NONE;
+
+ if (command_location != TOOLBAR_NONE)
{
- has_command = mToolbarLeft->hasCommand(commandId);
+ rank = mToolbars[command_location]->removeCommand(commandId);
}
- if (mToolbarRight && !has_command)
+
+ return command_location;
+}
+
+S32 LLToolBarView::enableCommand(const LLCommandId& commandId, bool enabled)
+{
+ S32 command_location = hasCommand(commandId);
+
+ if (command_location != TOOLBAR_NONE)
+ {
+ mToolbars[command_location]->enableCommand(commandId, enabled);
+ }
+
+ return command_location;
+}
+
+S32 LLToolBarView::stopCommandInProgress(const LLCommandId& commandId)
+{
+ S32 command_location = hasCommand(commandId);
+
+ if (command_location != TOOLBAR_NONE)
{
- has_command = mToolbarRight->hasCommand(commandId);
+ mToolbars[command_location]->stopCommandInProgress(commandId);
}
- if (mToolbarBottom && !has_command)
+
+ return command_location;
+}
+
+S32 LLToolBarView::flashCommand(const LLCommandId& commandId, bool flash)
+{
+ S32 command_location = hasCommand(commandId);
+
+ if (command_location != TOOLBAR_NONE)
{
- has_command = mToolbarBottom->hasCommand(commandId);
+ mToolbars[command_location]->flashCommand(commandId, flash);
}
- return has_command;
+
+ return command_location;
}
-bool LLToolBarView::addCommand(const LLCommandId& command, LLToolBar* toolbar)
+bool LLToolBarView::addCommandInternal(const LLCommandId& command, LLToolBar* toolbar)
{
LLCommandManager& mgr = LLCommandManager::instance();
if (mgr.getCommand(command))
@@ -147,6 +206,7 @@ bool LLToolBarView::addCommand(const LLCommandId& command, LLToolBar* toolbar)
bool LLToolBarView::loadToolbars(bool force_default)
{
LLToolBarView::ToolbarSet toolbar_set;
+ bool err = false;
// Load the toolbars.xml file
std::string toolbar_file = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "toolbars.xml");
@@ -164,80 +224,90 @@ bool LLToolBarView::loadToolbars(bool force_default)
if(!LLXMLNode::parseFile(toolbar_file, root, NULL))
{
llwarns << "Unable to load toolbars from file: " << toolbar_file << llendl;
- return false;
+ err = true;
}
- if(!root->hasName("toolbars"))
+
+ if (!err && !root->hasName("toolbars"))
{
llwarns << toolbar_file << " is not a valid toolbars definition file" << llendl;
- return false;
+ err = true;
}
// Parse the toolbar settings
LLXUIParser parser;
+ if (!err)
+ {
parser.readXUI(root, toolbar_set, toolbar_file);
- if (!toolbar_set.validateBlock())
+ }
+ if (!err && !toolbar_set.validateBlock())
{
- llerrs << "Unable to validate toolbars from file: " << toolbar_file << llendl;
- return false;
+ llwarns << "Unable to validate toolbars from file: " << toolbar_file << llendl;
+ err = true;
}
- // Clear the toolbars now before adding the loaded commands and settings
- if (mToolbarLeft)
+ if (err)
{
- mToolbarLeft->clearCommandsList();
+ if (force_default)
+ {
+ llerrs << "Unable to load toolbars from default file : " << toolbar_file << llendl;
+ return false;
}
- if (mToolbarRight)
- {
- mToolbarRight->clearCommandsList();
+ // Try to load the default toolbars
+ return loadToolbars(true);
}
- if (mToolbarBottom)
+
+ // Clear the toolbars now before adding the loaded commands and settings
+ for (S32 i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
{
- mToolbarBottom->clearCommandsList();
+ if (mToolbars[i])
+ {
+ mToolbars[i]->clearCommandsList();
+ }
}
// Add commands to each toolbar
- if (toolbar_set.left_toolbar.isProvided() && mToolbarLeft)
+ if (toolbar_set.left_toolbar.isProvided() && mToolbars[TOOLBAR_LEFT])
{
if (toolbar_set.left_toolbar.button_display_mode.isProvided())
{
LLToolBarEnums::ButtonType button_type = toolbar_set.left_toolbar.button_display_mode;
- mToolbarLeft->setButtonType(button_type);
+ mToolbars[TOOLBAR_LEFT]->setButtonType(button_type);
}
- BOOST_FOREACH(const LLCommandId::Params& command_name_param, toolbar_set.left_toolbar.commands)
+ BOOST_FOREACH(const LLCommandId::Params& command_params, toolbar_set.left_toolbar.commands)
{
- if (addCommand(LLCommandId(command_name_param), mToolbarLeft) == false)
+ if (addCommandInternal(LLCommandId(command_params), mToolbars[TOOLBAR_LEFT]))
{
- llwarns << "Error adding command '" << command_name_param.name() << "' to left toolbar." << llendl;
+ llwarns << "Error adding command '" << command_params.name() << "' to left toolbar." << llendl;
}
}
}
- if (toolbar_set.right_toolbar.isProvided() && mToolbarRight)
+ if (toolbar_set.right_toolbar.isProvided() && mToolbars[TOOLBAR_RIGHT])
{
if (toolbar_set.right_toolbar.button_display_mode.isProvided())
{
LLToolBarEnums::ButtonType button_type = toolbar_set.right_toolbar.button_display_mode;
- mToolbarRight->setButtonType(button_type);
+ mToolbars[TOOLBAR_RIGHT]->setButtonType(button_type);
}
- BOOST_FOREACH(const LLCommandId::Params& command_name_param, toolbar_set.right_toolbar.commands)
+ BOOST_FOREACH(const LLCommandId::Params& command_params, toolbar_set.right_toolbar.commands)
{
- if (addCommand(LLCommandId(command_name_param), mToolbarRight) == false)
+ if (addCommandInternal(LLCommandId(command_params), mToolbars[TOOLBAR_RIGHT]))
{
- llwarns << "Error adding command '" << command_name_param.name() << "' to right toolbar." << llendl;
+ llwarns << "Error adding command '" << command_params.name() << "' to right toolbar." << llendl;
}
}
}
- if (toolbar_set.bottom_toolbar.isProvided() && mToolbarBottom)
+ if (toolbar_set.bottom_toolbar.isProvided() && mToolbars[TOOLBAR_BOTTOM])
{
if (toolbar_set.bottom_toolbar.button_display_mode.isProvided())
{
LLToolBarEnums::ButtonType button_type = toolbar_set.bottom_toolbar.button_display_mode;
- mToolbarBottom->setButtonType(button_type);
+ mToolbars[TOOLBAR_BOTTOM]->setButtonType(button_type);
}
- BOOST_FOREACH(const LLCommandId::Params& command_name_param, toolbar_set.bottom_toolbar.commands)
+ BOOST_FOREACH(const LLCommandId::Params& command_params, toolbar_set.bottom_toolbar.commands)
{
- if (addCommand(LLCommandId(command_name_param), mToolbarBottom) == false)
+ if (addCommandInternal(LLCommandId(command_params), mToolbars[TOOLBAR_BOTTOM]))
{
- llwarns << "Error adding command '" << command_name_param.name() << "' to bottom toolbar." << llendl;
+ llwarns << "Error adding command '" << command_params.name() << "' to bottom toolbar." << llendl;
}
}
}
@@ -269,20 +339,20 @@ void LLToolBarView::saveToolbars() const
// Build the parameter tree from the toolbar data
LLToolBarView::ToolbarSet toolbar_set;
- if (mToolbarLeft)
+ if (mToolbars[TOOLBAR_LEFT])
{
- toolbar_set.left_toolbar.button_display_mode = mToolbarLeft->getButtonType();
- addToToolset(mToolbarLeft->getCommandsList(),toolbar_set.left_toolbar);
+ toolbar_set.left_toolbar.button_display_mode = mToolbars[TOOLBAR_LEFT]->getButtonType();
+ addToToolset(mToolbars[TOOLBAR_LEFT]->getCommandsList(), toolbar_set.left_toolbar);
}
- if (mToolbarRight)
+ if (mToolbars[TOOLBAR_RIGHT])
{
- toolbar_set.right_toolbar.button_display_mode = mToolbarRight->getButtonType();
- addToToolset(mToolbarRight->getCommandsList(),toolbar_set.right_toolbar);
+ toolbar_set.right_toolbar.button_display_mode = mToolbars[TOOLBAR_RIGHT]->getButtonType();
+ addToToolset(mToolbars[TOOLBAR_RIGHT]->getCommandsList(), toolbar_set.right_toolbar);
}
- if (mToolbarBottom)
+ if (mToolbars[TOOLBAR_BOTTOM])
{
- toolbar_set.bottom_toolbar.button_display_mode = mToolbarBottom->getButtonType();
- addToToolset(mToolbarBottom->getCommandsList(),toolbar_set.bottom_toolbar);
+ toolbar_set.bottom_toolbar.button_display_mode = mToolbars[TOOLBAR_BOTTOM]->getButtonType();
+ addToToolset(mToolbars[TOOLBAR_BOTTOM]->getCommandsList(), toolbar_set.bottom_toolbar);
}
// Serialize the parameter tree
@@ -323,35 +393,122 @@ void LLToolBarView::addToToolset(command_id_list_t& command_list, Toolbar& toolb
}
}
-void LLToolBarView::draw()
+void LLToolBarView::onToolBarButtonAdded(LLView* button)
{
- //LLPanel* sizer_left = getChild<LLPanel>("sizer_left");
+ llassert(button);
- LLRect bottom_rect, left_rect, right_rect;
+ 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->getName() == "voice")
+ {
+ // Add the "Voice controls" button as a control view in LLTransientFloaterMgr
+ // to prevent hiding the transient IM floater upon pressing "Voice controls".
+ LLTransientFloaterMgr::getInstance()->addControlView(button);
+ }
+}
- if (mToolbarBottom)
+void LLToolBarView::onToolBarButtonRemoved(LLView* button)
+{
+ llassert(button);
+
+ if (button->getName() == "speak")
{
- mToolbarBottom->getParent()->reshape(mToolbarBottom->getParent()->getRect().getWidth(), mToolbarBottom->getRect().getHeight());
- mToolbarBottom->localRectToOtherView(mToolbarBottom->getLocalRect(), &bottom_rect, this);
+ 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);
+ }
}
- if (mToolbarLeft)
+ else if (button->getName() == "voice")
{
- mToolbarLeft->getParent()->reshape(mToolbarLeft->getRect().getWidth(), mToolbarLeft->getParent()->getRect().getHeight());
- mToolbarLeft->localRectToOtherView(mToolbarLeft->getLocalRect(), &left_rect, this);
+ LLTransientFloaterMgr::getInstance()->removeControlView(button);
}
- if (mToolbarRight)
+}
+
+void LLToolBarView::draw()
+{
+ LLRect toolbar_rects[TOOLBAR_COUNT];
+
+ for (S32 i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
{
- mToolbarRight->getParent()->reshape(mToolbarRight->getRect().getWidth(), mToolbarRight->getParent()->getRect().getHeight());
- mToolbarRight->localRectToOtherView(mToolbarRight->getLocalRect(), &right_rect, this);
+ if (mToolbars[i])
+ {
+ LLLayoutStack::ELayoutOrientation orientation = LLToolBarEnums::getOrientation(mToolbars[i]->getSideType());
+
+ if (orientation == LLLayoutStack::HORIZONTAL)
+ {
+ mToolbars[i]->getParent()->reshape(mToolbars[i]->getParent()->getRect().getWidth(), mToolbars[i]->getRect().getHeight());
+ }
+ else
+ {
+ mToolbars[i]->getParent()->reshape(mToolbars[i]->getRect().getWidth(), mToolbars[i]->getParent()->getRect().getHeight());
+ }
+
+ mToolbars[i]->localRectToOtherView(mToolbars[i]->getLocalRect(), &toolbar_rects[i], this);
+ }
}
// Draw drop zones if drop of a tool is active
if (isToolDragged())
{
LLColor4 drop_color = LLUIColorTable::instance().getColor( "ToolbarDropZoneColor" );
- gl_rect_2d(bottom_rect, drop_color, TRUE);
- gl_rect_2d(left_rect, drop_color, TRUE);
- gl_rect_2d(right_rect, drop_color, TRUE);
+
+ for (S32 i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
+ {
+ gl_rect_2d(toolbar_rects[i], drop_color, TRUE);
+ }
}
LLUICtrl::draw();
@@ -363,9 +520,9 @@ void LLToolBarView::draw()
// ----------------------------------------
-void LLToolBarView::startDragTool(S32 x, S32 y, LLToolBarButton* button)
+void LLToolBarView::startDragTool(S32 x, S32 y, LLToolBarButton* toolbarButton)
{
- resetDragTool(button);
+ resetDragTool(toolbarButton);
// Flag the tool dragging but don't start it yet
LLToolDragAndDrop::getInstance()->setDragStart( x, y );
@@ -391,9 +548,7 @@ BOOL LLToolBarView::handleDragTool( S32 x, S32 y, const LLUUID& uuid, LLAssetTyp
// Second, stop the command if it is in progress and requires stopping!
LLCommandId command_id = LLCommandId(uuid);
- gToolBarView->mToolbarLeft->stopCommandInProgress(command_id);
- gToolBarView->mToolbarRight->stopCommandInProgress(command_id);
- gToolBarView->mToolbarBottom->stopCommandInProgress(command_id);
+ gToolBarView->stopCommandInProgress(command_id);
gToolBarView->mDragStarted = true;
return TRUE;
@@ -424,10 +579,10 @@ BOOL LLToolBarView::handleDropTool( void* cargo_data, S32 x, S32 y, LLToolBar* t
{
// Suppress the command from the toolbars (including the one it's dropped in,
// this will handle move position).
- bool command_present = gToolBarView->hasCommand(command_id);
+ S32 old_toolbar_loc = gToolBarView->hasCommand(command_id);
LLToolBar* old_toolbar = NULL;
- if (command_present)
+ if (old_toolbar_loc != TOOLBAR_NONE)
{
llassert(gToolBarView->mDragToolbarButton);
old_toolbar = gToolBarView->mDragToolbarButton->getParentByType<LLToolBar>();
@@ -437,9 +592,8 @@ BOOL LLToolBarView::handleDropTool( void* cargo_data, S32 x, S32 y, LLToolBar* t
}
else
{
- gToolBarView->mToolbarBottom->removeCommand(command_id);
- gToolBarView->mToolbarLeft->removeCommand(command_id);
- gToolBarView->mToolbarRight->removeCommand(command_id);
+ int old_rank = LLToolBar::RANK_NONE;
+ gToolBarView->removeCommand(command_id, old_rank);
}
}
@@ -463,27 +617,29 @@ BOOL LLToolBarView::handleDropTool( void* cargo_data, S32 x, S32 y, LLToolBar* t
return handled;
}
-void LLToolBarView::resetDragTool(LLToolBarButton* button)
+void LLToolBarView::resetDragTool(LLToolBarButton* toolbarButton)
{
// Clear the saved command, toolbar and rank
gToolBarView->mDragStarted = false;
- gToolBarView->mDragToolbarButton = button;
+ gToolBarView->mDragToolbarButton = toolbarButton;
}
void LLToolBarView::setToolBarsVisible(bool visible)
{
- mToolbarBottom->getParent()->setVisible(visible);
- mToolbarLeft->getParent()->setVisible(visible);
- mToolbarRight->getParent()->setVisible(visible);
+ for (S32 i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
+ {
+ mToolbars[i]->getParent()->setVisible(visible);
+ }
}
bool LLToolBarView::isModified() const
{
bool modified = false;
- modified |= mToolbarBottom->isModified();
- modified |= mToolbarLeft->isModified();
- modified |= mToolbarRight->isModified();
+ for (S32 i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
+ {
+ modified |= mToolbars[i]->isModified();
+ }
return modified;
}
@@ -496,9 +652,11 @@ bool LLToolBarView::isModified() const
void handleLoginToolbarSetup()
{
// Open the destinations guide by default on first login, per Rhett
- if (gSavedSettings.getBOOL("FirstLoginThisInstall") || gAgent.isFirstLogin())
+ if (gSavedPerAccountSettings.getBOOL("DisplayDestinationsOnInitialRun") || gAgent.isFirstLogin())
{
LLFloaterReg::showInstance("destinations");
+
+ gSavedPerAccountSettings.setBOOL("DisplayDestinationsOnInitialRun", FALSE);
}
}
diff --git a/indra/newview/lltoolbarview.h b/indra/newview/lltoolbarview.h
index 2b26db3802..4307d10258 100644
--- a/indra/newview/lltoolbarview.h
+++ b/indra/newview/lltoolbarview.h
@@ -39,6 +39,19 @@ class LLUICtrlFactory;
class LLToolBarView : public LLUICtrl
{
public:
+ typedef enum
+ {
+ TOOLBAR_NONE = 0,
+ TOOLBAR_LEFT,
+ TOOLBAR_RIGHT,
+ TOOLBAR_BOTTOM,
+
+ TOOLBAR_COUNT,
+
+ TOOLBAR_FIRST = TOOLBAR_LEFT,
+ TOOLBAR_LAST = TOOLBAR_BOTTOM,
+ } EToolBarLocation;
+
// Xui structure of the toolbar panel
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> {};
@@ -52,6 +65,7 @@ public:
{
Mandatory<LLToolBarEnums::ButtonType> button_display_mode;
Multiple<LLCommandId::Params> commands;
+
Toolbar();
};
struct ToolbarSet : public LLInitParam::Block<ToolbarSet>
@@ -59,6 +73,7 @@ public:
Optional<Toolbar> left_toolbar,
right_toolbar,
bottom_toolbar;
+
ToolbarSet();
};
@@ -66,9 +81,16 @@ public:
virtual ~LLToolBarView();
virtual BOOL postBuild();
virtual void draw();
+
// Toolbar view interface with the rest of the world
- // Checks if the commandId is being used somewhere in one of the toolbars
- bool hasCommand(const LLCommandId& commandId) const;
+ // Checks if the commandId is being used somewhere in one of the toolbars, returns EToolBarLocation
+ S32 hasCommand(const LLCommandId& commandId) const;
+ S32 addCommand(const LLCommandId& commandId, EToolBarLocation toolbar, int rank = LLToolBar::RANK_NONE);
+ S32 removeCommand(const LLCommandId& commandId, int& rank); // Sets the rank the removed command was at, RANK_NONE if not found
+ S32 enableCommand(const LLCommandId& commandId, bool enabled);
+ S32 stopCommandInProgress(const LLCommandId& commandId);
+ S32 flashCommand(const LLCommandId& commandId, bool flash);
+
// Loads the toolbars from the existing user or default settings
bool loadToolbars(bool force_default = false); // return false if load fails
@@ -76,10 +98,10 @@ public:
static bool loadDefaultToolbars();
- static void startDragTool(S32 x, S32 y, LLToolBarButton* button);
+ static void startDragTool(S32 x, S32 y, LLToolBarButton* toolbarButton);
static BOOL handleDragTool(S32 x, S32 y, const LLUUID& uuid, LLAssetType::EType type);
static BOOL handleDropTool(void* cargo_data, S32 x, S32 y, LLToolBar* toolbar);
- static void resetDragTool(LLToolBarButton* button);
+ static void resetDragTool(LLToolBarButton* toolbarButton);
bool isModified() const;
@@ -91,13 +113,14 @@ protected:
private:
void saveToolbars() const;
- bool addCommand(const LLCommandId& commandId, LLToolBar* toolbar);
+ bool addCommandInternal(const LLCommandId& commandId, LLToolBar* toolbar);
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* mToolbarLeft;
- LLToolBar* mToolbarRight;
- LLToolBar* mToolbarBottom;
+ LLToolBar* mToolbars[TOOLBAR_COUNT];
bool mToolbarsLoaded;
bool mDragStarted;
diff --git a/indra/newview/lltransientfloatermgr.cpp b/indra/newview/lltransientfloatermgr.cpp
index c648a6a28a..3d68c10489 100644
--- a/indra/newview/lltransientfloatermgr.cpp
+++ b/indra/newview/lltransientfloatermgr.cpp
@@ -42,9 +42,9 @@ LLTransientFloaterMgr::LLTransientFloaterMgr()
&LLTransientFloaterMgr::leftMouseClickCallback, this, _2, _3, _4));
}
- mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(GLOBAL, std::set<LLView*>()));
- mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(DOCKED, std::set<LLView*>()));
- mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(IM, std::set<LLView*>()));
+ mGroupControls.insert(std::pair<ETransientGroup, controls_set_t >(GLOBAL, controls_set_t()));
+ mGroupControls.insert(std::pair<ETransientGroup, controls_set_t >(DOCKED, controls_set_t()));
+ mGroupControls.insert(std::pair<ETransientGroup, controls_set_t >(IM, controls_set_t()));
}
void LLTransientFloaterMgr::registerTransientFloater(LLTransientFloater* floater)
@@ -59,12 +59,16 @@ void LLTransientFloaterMgr::unregisterTransientFloater(LLTransientFloater* float
void LLTransientFloaterMgr::addControlView(ETransientGroup group, LLView* view)
{
- mGroupControls.find(group)->second.insert(view);
+ if (!view) return;
+
+ mGroupControls.find(group)->second.insert(view->getHandle());
}
void LLTransientFloaterMgr::removeControlView(ETransientGroup group, LLView* view)
{
- mGroupControls.find(group)->second.erase(view);
+ if (!view) return;
+
+ mGroupControls.find(group)->second.erase(view->getHandle());
}
void LLTransientFloaterMgr::addControlView(LLView* view)
@@ -89,7 +93,7 @@ void LLTransientFloaterMgr::hideTransientFloaters(S32 x, S32 y)
{
ETransientGroup group = floater->getGroup();
- bool hide = isControlClicked(mGroupControls.find(group)->second, x, y);
+ bool hide = isControlClicked(group, mGroupControls.find(group)->second, x, y);
if (hide)
{
floater->setTransientVisible(FALSE);
@@ -98,13 +102,25 @@ void LLTransientFloaterMgr::hideTransientFloaters(S32 x, S32 y)
}
}
-bool LLTransientFloaterMgr::isControlClicked(std::set<LLView*>& set, S32 x, S32 y)
+bool LLTransientFloaterMgr::isControlClicked(ETransientGroup group, controls_set_t& set, S32 x, S32 y)
{
+ std::list< LLHandle<LLView> > dead_handles;
+
bool res = true;
for (controls_set_t::iterator it = set.begin(); it
!= set.end(); it++)
{
- LLView* control_view = *it;
+ LLView* control_view = NULL;
+
+ LLHandle<LLView> handle = *it;
+ if (handle.isDead())
+ {
+ dead_handles.push_back(handle);
+ continue;
+ }
+
+ control_view = handle.get();
+
if (!control_view->getVisible())
{
continue;
@@ -118,6 +134,13 @@ bool LLTransientFloaterMgr::isControlClicked(std::set<LLView*>& set, S32 x, S32
break;
}
}
+
+ for (std::list< LLHandle<LLView> >::iterator it = dead_handles.begin(); it != dead_handles.end(); ++it)
+ {
+ LLHandle<LLView> handle = *it;
+ mGroupControls.find(group)->second.erase(handle);
+ }
+
return res;
}
@@ -130,8 +153,8 @@ void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y,
return;
}
- bool hide = isControlClicked(mGroupControls.find(DOCKED)->second, x, y)
- && isControlClicked(mGroupControls.find(GLOBAL)->second, x, y);
+ bool hide = isControlClicked(DOCKED, mGroupControls.find(DOCKED)->second, x, y)
+ && isControlClicked(GLOBAL, mGroupControls.find(GLOBAL)->second, x, y);
if (hide)
{
hideTransientFloaters(x, y);
diff --git a/indra/newview/lltransientfloatermgr.h b/indra/newview/lltransientfloatermgr.h
index 2919244121..b4611c8c87 100644
--- a/indra/newview/lltransientfloatermgr.h
+++ b/indra/newview/lltransientfloatermgr.h
@@ -56,14 +56,15 @@ public:
void removeControlView(LLView* view);
private:
+ typedef std::set<LLHandle<LLView> > controls_set_t;
+ typedef std::map<ETransientGroup, controls_set_t > group_controls_t;
+
void hideTransientFloaters(S32 x, S32 y);
void leftMouseClickCallback(S32 x, S32 y, MASK mask);
- bool isControlClicked(std::set<LLView*>& set, S32 x, S32 y);
-private:
+ bool isControlClicked(ETransientGroup group, controls_set_t& set, S32 x, S32 y);
+
std::set<LLTransientFloater*> mTransSet;
- typedef std::set<LLView*> controls_set_t;
- typedef std::map<ETransientGroup, std::set<LLView*> > group_controls_t;
group_controls_t mGroupControls;
};
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 0909714951..22d95563d8 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -7970,6 +7970,9 @@ void initialize_menus()
view_listener_t::addEnable(new LLUploadCostCalculator(), "Upload.CalculateCosts");
+
+ commit.add("Inventory.NewWindow", boost::bind(&LLFloaterInventory::showAgentInventory));
+
// Agent
commit.add("Agent.toggleFlying", boost::bind(&LLAgent::toggleFlying));
enable.add("Agent.enableFlying", boost::bind(&LLAgent::enableFlying));
@@ -8345,6 +8348,8 @@ void initialize_menus()
view_listener_t::addMenu(new LLGoToObject(), "GoToObject");
commit.add("PayObject", boost::bind(&handle_give_money_dialog));
+ commit.add("Inventory.NewWindow", boost::bind(&LLFloaterInventory::showAgentInventory));
+
enable.add("EnablePayObject", boost::bind(&enable_pay_object));
enable.add("EnablePayAvatar", boost::bind(&enable_pay_avatar));
enable.add("EnableEdit", boost::bind(&enable_object_edit));
diff --git a/indra/newview/skins/default/textures/windows/Flyout_Left.png b/indra/newview/skins/default/textures/windows/Flyout_Left.png
new file mode 100644
index 0000000000..6ac9fe2efd
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Flyout_Left.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/windows/Flyout_Right.png b/indra/newview/skins/default/textures/windows/Flyout_Right.png
new file mode 100644
index 0000000000..aa1f0625aa
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Flyout_Right.png
Binary files differ
diff --git a/indra/newview/skins/default/xui/en/floater_chat_bar.xml b/indra/newview/skins/default/xui/en/floater_chat_bar.xml
index 989b4a0580..87606c1a2a 100644
--- a/indra/newview/skins/default/xui/en/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/floater_chat_bar.xml
@@ -15,6 +15,7 @@
min_height="60"
min_width="150"
can_resize="true"
+ default_tab_group="1"
name="chat_bar"
width="380">
<panel
@@ -26,50 +27,56 @@
visible="false"
filename="panel_nearby_chat.xml"
name="nearby_chat" />
- <panel width="380" height="31" left="0" bottom="-1" follows="left|right|bottom">
- <line_editor
- border_style="line"
- border_thickness="1"
- follows="left|right"
- height="23"
- label="Click here to chat."
- layout="topleft"
- left_delta="7"
- left="0"
- max_length_bytes="1023"
- name="chat_box"
- text_pad_left="5"
- text_pad_right="25"
- tool_tip="Press Enter to say, Ctrl+Enter to shout"
- top="2"
- width="335" />
- <output_monitor
- auto_update="true"
- follows="right"
- draw_border="false"
- height="16"
- layout="topleft"
- left_pad="-24"
- mouse_opaque="true"
- name="chat_zone_indicator"
- top="6"
- visible="true"
- width="20" />
- <button
- follows="right"
- is_toggle="true"
- width="20"
- top="2"
- layout="topleft"
- left_pad="12"
- image_disabled="ComboButton_UpOff"
- image_unselected="ComboButton_UpOff"
- image_selected="ComboButton_On"
- image_pressed="ComboButton_UpSelected"
- image_pressed_selected="ComboButton_Selected"
- height="23"
- name="show_nearby_chat"
- tool_tip="Shows/hides nearby chat log">
- </button>
+ <panel width="380"
+ height="31"
+ left="0"
+ bottom="-1"
+ follows="left|right|bottom"
+ tab_group="1">
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|right"
+ height="23"
+ label="Click here to chat."
+ layout="topleft"
+ left_delta="7"
+ left="0"
+ max_length_bytes="1023"
+ name="chat_box"
+ text_pad_left="5"
+ text_pad_right="25"
+ tool_tip="Press Enter to say, Ctrl+Enter to shout"
+ top="2"
+ width="335" />
+ <output_monitor
+ auto_update="true"
+ follows="right"
+ draw_border="false"
+ height="16"
+ layout="topleft"
+ left_pad="-24"
+ mouse_opaque="true"
+ name="chat_zone_indicator"
+ top="6"
+ visible="true"
+ width="20" />
+ <button
+ follows="right"
+ is_toggle="true"
+ width="20"
+ top="2"
+ layout="topleft"
+ left_pad="12"
+ image_disabled="ComboButton_UpOff"
+ image_unselected="ComboButton_UpOff"
+ image_selected="ComboButton_On"
+ image_pressed="ComboButton_UpSelected"
+ image_pressed_selected="ComboButton_Selected"
+ height="23"
+ chrome="true"
+ name="show_nearby_chat"
+ tool_tip="Shows/hides nearby chat log">
+ </button>
</panel>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_outgoing_call.xml b/indra/newview/skins/default/xui/en/floater_outgoing_call.xml
index 9db6568ee3..ffbb6aa28b 100644
--- a/indra/newview/skins/default/xui/en/floater_outgoing_call.xml
+++ b/indra/newview/skins/default/xui/en/floater_outgoing_call.xml
@@ -8,6 +8,7 @@
layout="topleft"
name="outgoing call"
help_topic="outgoing_call"
+ save_dock_state="true"
title="CALLING"
width="410">
<floater.string
diff --git a/indra/newview/skins/default/xui/en/floater_toybox.xml b/indra/newview/skins/default/xui/en/floater_toybox.xml
index c7e09bf45e..ef3951a1cd 100644
--- a/indra/newview/skins/default/xui/en/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/en/floater_toybox.xml
@@ -13,7 +13,7 @@
open_positioning="centered"
save_rect="true"
single_instance="true"
- title="CUSTOMIZE TOOLBARS"
+ title="TOOLBAR BUTTONS"
width="650">
<text
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/floater_voice_controls.xml b/indra/newview/skins/default/xui/en/floater_voice_controls.xml
index 93a04050b6..6807b01fa3 100644
--- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml
@@ -89,7 +89,7 @@
visible="true"
width="20" />
</layout_panel>
- <layout_panel name="leave_call_panel" height="26" auto_resize="false">
+ <layout_panel name="leave_call_panel" height="26" min_height="26" user_resize="false" auto_resize="false">
<layout_stack
clip="true"
follows="left|top|right"
diff --git a/indra/newview/skins/default/xui/en/menu_toolbars.xml b/indra/newview/skins/default/xui/en/menu_toolbars.xml
index 59912b5503..7384114d7d 100644
--- a/indra/newview/skins/default/xui/en/menu_toolbars.xml
+++ b/indra/newview/skins/default/xui/en/menu_toolbars.xml
@@ -3,7 +3,7 @@
layout="topleft"
name="Toolbars Popup"
visible="false">
- <menu_item_call label="Choose buttons..."
+ <menu_item_call label="Toolbar buttons..."
layout="topleft"
name="Chose Buttons">
<menu_item_call.on_click function="Floater.Show"
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 01f9c23afd..9c44d90a6e 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -43,6 +43,15 @@
function="Floater.Toggle"
parameter="inventory" />
</menu_item_check>
+ <menu_item_call
+ label="New Inventory Window"
+ name="NewInventoryWindow"
+ shortcut="control|shift|I"
+ visible="false">
+ <menu_item_call.on_click
+ function="Inventory.NewWindow"
+ parameter="" />
+ </menu_item_call>
<menu_item_check
label="Gestures..."
name="Gestures"
@@ -166,7 +175,7 @@
parameter="preferences" />
</menu_item_call>
<menu_item_call
- label="Toolbars..."
+ label="Toolbar buttons..."
name="Toolbars"
shortcut="control|T">
<menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml
index 422bbada7f..3239c4e531 100644
--- a/indra/newview/skins/default/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -2,7 +2,7 @@
<panel
background_opaque="true"
background_visible="true"
- bg_opaque_color="MouseGray"
+ bg_opaque_color="DkGray"
chrome="true"
follows="top|right"
height="19"
@@ -39,10 +39,7 @@
width="160"
top="1"
follows="right|top"
- name="balance_bg"
- bg_visible="true"
- background_opaque="true"
- bg_opaque_image="bevel_background">
+ name="balance_bg">
<text
halign="center"
font="SansSerifSmall"
diff --git a/indra/newview/skins/default/xui/en/panel_topinfo_bar.xml b/indra/newview/skins/default/xui/en/panel_topinfo_bar.xml
index 79f29777ce..fc527f5f9d 100644
--- a/indra/newview/skins/default/xui/en/panel_topinfo_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_topinfo_bar.xml
@@ -4,7 +4,7 @@
background_opaque="false"
bg_opaque_color="Black_50"
bg_alpha_color="Black_50"
- follows="left|top|right"
+ follows="left|top"
height="19"
layout="topleft"
name="topinfo_bar"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 24cec13c4c..ec230773cc 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2271,7 +2271,7 @@ Returns a string with the requested data about the region
<string name="NextStipendDay" value="The next stipend day is " />
<string name="GroupPlanningDate">[mthnum,datetime,utc]/[day,datetime,utc]/[year,datetime,utc]</string>
<string name="GroupIndividualShare" value=" Group Individual Share" />
- <string name="GroupColumn" value=" Group" />
+ <string name="GroupColumn" value=" Group" />
<string name="Balance">Balance</string>
<string name="Credits">Credits</string>
<string name="Debits">Debits</string>
@@ -3711,6 +3711,10 @@ Try enclosing path to the editor with double quotes.
<string name="Command_View_Tooltip">Changing camera angle</string>
<string name="Command_Voice_Tooltip">Volume controls for calls and people near you in world</string>
+ <string name="Toolbar_Bottom_Tooltip">currently in your bottom toolbar</string>
+ <string name="Toolbar_Left_Tooltip" >currently in your left toolbar</string>
+ <string name="Toolbar_Right_Tooltip" >currently in your right toolbar</string>
+
<!-- Mesh UI terms -->
<string name="Retain%">Retain%</string>
<string name="Detail">Detail</string>
diff --git a/indra/newview/skins/default/xui/en/widgets/toolbar.xml b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
index 7e7a9c61cf..0aa478ace9 100644
--- a/indra/newview/skins/default/xui/en/widgets/toolbar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
@@ -30,6 +30,8 @@
image_overlay_alignment="left"
use_ellipses="true"
auto_resize="true"
+ button_flash_count="99999"
+ button_flash_rate="1.0"
flash_color="EmphasisColor"/>
<button_icon pad_left="10"
pad_right="10"
@@ -49,5 +51,7 @@
chrome="true"
use_ellipses="true"
auto_resize="true"
+ button_flash_count="99999"
+ button_flash_rate="1.0"
flash_color="EmphasisColor"/>
</toolbar>