summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/llcombobox.cpp29
-rw-r--r--indra/llui/llcombobox.h3
-rw-r--r--indra/llui/lldockcontrol.cpp720
-rw-r--r--indra/llui/lllayoutstack.cpp10
-rw-r--r--indra/llui/llnotifications.cpp53
-rw-r--r--indra/llui/llnotifications.h11
-rw-r--r--indra/llui/lluictrlfactory.cpp22
-rw-r--r--indra/llui/llview.cpp2
8 files changed, 451 insertions, 399 deletions
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 8b6a73af56..6f9893b07a 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -316,7 +316,7 @@ void LLComboBox::setValue(const LLSD& value)
LLScrollListItem* item = mList->getFirstSelected();
if (item)
{
- setLabel(getSelectedItemLabel());
+ updateLabel();
}
mLastSelectedIndex = mList->getFirstSelectedIndex();
}
@@ -384,6 +384,23 @@ void LLComboBox::setLabel(const LLStringExplicit& name)
}
}
+void LLComboBox::updateLabel()
+{
+ // Update the combo editor with the selected
+ // item label.
+ if (mTextEntry)
+ {
+ mTextEntry->setText(getSelectedItemLabel());
+ mTextEntry->setTentative(FALSE);
+ }
+
+ // If combo box doesn't allow text entry update
+ // the combo button label.
+ if (!mAllowTextEntry)
+ {
+ mButton->setLabel(getSelectedItemLabel());
+ }
+}
BOOL LLComboBox::remove(const std::string& name)
{
@@ -701,13 +718,13 @@ void LLComboBox::onItemSelected(const LLSD& data)
mLastSelectedIndex = getCurrentIndex();
if (mLastSelectedIndex != -1)
{
- setLabel(getSelectedItemLabel());
+ updateLabel();
if (mAllowTextEntry)
- {
- gFocusMgr.setKeyboardFocus(mTextEntry);
- mTextEntry->selectAll();
- }
+ {
+ gFocusMgr.setKeyboardFocus(mTextEntry);
+ mTextEntry->selectAll();
+ }
}
// hiding the list reasserts the old value stored in the text editor/dropdown button
hideList();
diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h
index 74d64269bd..e9ef9d07e4 100644
--- a/indra/llui/llcombobox.h
+++ b/indra/llui/llcombobox.h
@@ -148,6 +148,9 @@ public:
// This is probably a UI abuse.
void setLabel(const LLStringExplicit& name);
+ // Updates the combobox label to match the selected list item.
+ void updateLabel();
+
BOOL remove(const std::string& name); // remove item "name", return TRUE if found and removed
BOOL setCurrentByIndex( S32 index );
diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index e18309ac33..3f81c2b28f 100644
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -1,359 +1,361 @@
-/**
- * @file lldockcontrol.cpp
- * @brief Creates a panel of a specific kind for a toast
- *
- * $LicenseInfo:firstyear=2000&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-
-#include "lldockcontrol.h"
-#include "lldockablefloater.h"
-
-LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
- const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) :
- mDockWidget(dockWidget),
- mDockableFloater(dockableFloater),
- mDockTongue(dockTongue),
- mDockTongueX(0),
- mDockTongueY(0)
-{
- mDockAt = dockAt;
-
- if (dockableFloater->isDocked())
- {
- on();
- }
- else
- {
- off();
- }
-
- if (!(get_allowed_rect_callback))
- {
- mGetAllowedRectCallback = boost::bind(&LLDockControl::getAllowedRect, this, _1);
- }
- else
- {
- mGetAllowedRectCallback = get_allowed_rect_callback;
- }
-
- if (dockWidget != NULL)
- {
- repositionDockable();
- }
-
- if (mDockWidget != NULL)
- {
- mDockWidgetVisible = isDockVisible();
- }
- else
- {
- mDockWidgetVisible = false;
- }
-}
-
-LLDockControl::~LLDockControl()
-{
-}
-
-void LLDockControl::setDock(LLView* dockWidget)
-{
- mDockWidget = dockWidget;
- if (mDockWidget != NULL)
- {
- repositionDockable();
- mDockWidgetVisible = isDockVisible();
- }
- else
- {
- mDockWidgetVisible = false;
- }
-}
-
-void LLDockControl::getAllowedRect(LLRect& rect)
-{
- rect = mDockableFloater->getRootView()->getRect();
-}
-
-void LLDockControl::repositionDockable()
-{
- LLRect dockRect = mDockWidget->calcScreenRect();
- LLRect rootRect;
- 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)
- {
- // undock dockable and off() if dock not visible
- if (!isDockVisible())
- {
- mDockableFloater->setDocked(false);
- // force off() since dockable may not have dockControll at this time
- off();
- LLDockableFloater* dockable_floater =
- dynamic_cast<LLDockableFloater*> (mDockableFloater);
- if(dockable_floater != NULL)
- {
- dockable_floater->onDockHidden();
- }
- }
- else
- {
- if(mEnabled)
- {
- moveDockable();
- }
- LLDockableFloater* dockable_floater =
- dynamic_cast<LLDockableFloater*> (mDockableFloater);
- if(dockable_floater != NULL)
- {
- dockable_floater->onDockShown();
- }
- }
-
- mPrevDockRect = dockRect;
- mRootRect = rootRect;
- mRecalculateDocablePosition = false;
- mDockWidgetVisible = isDockVisible();
- }
-}
-
-bool LLDockControl::isDockVisible()
-{
- bool res = true;
-
- if (mDockWidget != NULL)
- {
- //we should check all hierarchy
- res = mDockWidget->isInVisibleChain();
- if (res)
- {
- LLRect dockRect = mDockWidget->calcScreenRect();
-
- switch (mDockAt)
- {
- case LEFT: // to keep compiler happy
- break;
- case BOTTOM:
- case TOP:
- {
- // check is dock inside parent rect
- LLRect dockParentRect =
- mDockWidget->getParent()->calcScreenRect();
- if (dockRect.mRight <= dockParentRect.mLeft
- || dockRect.mLeft >= dockParentRect.mRight)
- {
- res = false;
- }
- break;
- }
- default:
- break;
- }
- }
- }
-
- return res;
-}
-
-void LLDockControl::moveDockable()
-{
- // calculate new dockable position
- LLRect dockRect = mDockWidget->calcScreenRect();
- LLRect rootRect;
- mGetAllowedRectCallback(rootRect);
-
- bool use_tongue = false;
- LLDockableFloater* dockable_floater =
- dynamic_cast<LLDockableFloater*> (mDockableFloater);
- if (dockable_floater != NULL)
- {
- use_tongue = dockable_floater->getUseTongue();
- }
-
- LLRect dockableRect = mDockableFloater->calcScreenRect();
- S32 x = 0;
- S32 y = 0;
- LLRect dockParentRect;
- 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 = rootRect.mLeft;
- }
- if (x + dockableRect.getWidth() > rootRect.mRight)
- {
- x = rootRect.mRight - dockableRect.getWidth();
- }
-
- mDockTongueX = x + dockableRect.getWidth()/2 - mDockTongue->getWidth() / 2;
-
- mDockTongueY = dockRect.mTop;
- break;
-
- case TOP:
- x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
- y = dockRect.mTop + dockableRect.getHeight();
- // unique docking used with dock tongue, so add tongue height to the Y coordinate
- if (use_tongue)
- {
- y += mDockTongue->getHeight();
-
- if ( y > rootRect.mTop)
- {
- y = rootRect.mTop;
- }
- }
-
- // check is dockable inside root view rect
- if (x < rootRect.mLeft)
- {
- x = rootRect.mLeft;
- }
- if (x + dockableRect.getWidth() > rootRect.mRight)
- {
- x = rootRect.mRight - dockableRect.getWidth();
- }
-
-
- // calculate dock tongue position
- dockParentRect = mDockWidget->getParent()->calcScreenRect();
- if (dockRect.getCenterX() < dockParentRect.mLeft)
- {
- mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
- }
- else if (dockRect.getCenterX() > dockParentRect.mRight)
- {
- mDockTongueX = dockParentRect.mRight - mDockTongue->getWidth() / 2;;
- }
- else
- {
- mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
- }
- mDockTongueY = dockRect.mTop;
-
- break;
- case BOTTOM:
- x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
- y = dockRect.mBottom;
- // unique docking used with dock tongue, so add tongue height to the Y coordinate
- if (use_tongue)
- {
- y -= mDockTongue->getHeight();
- }
-
- // check is dockable inside root view rect
- if (x < rootRect.mLeft)
- {
- x = rootRect.mLeft;
- }
- if (x + dockableRect.getWidth() > rootRect.mRight)
- {
- x = rootRect.mRight - dockableRect.getWidth();
- }
-
- // calculate dock tongue position
- dockParentRect = mDockWidget->getParent()->calcScreenRect();
- if (dockRect.getCenterX() < dockParentRect.mLeft)
- {
- mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
- }
- else if (dockRect.getCenterX() > dockParentRect.mRight)
- {
- mDockTongueX = dockParentRect.mRight - mDockTongue->getWidth() / 2;;
- }
- else
- {
- mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
- }
- mDockTongueY = dockRect.mBottom - mDockTongue->getHeight();
-
- break;
- }
-
- S32 max_available_height = rootRect.getHeight() - (rootRect.mBottom - mDockTongueY) - mDockTongue->getHeight();
-
- // A floater should be shrunk so it doesn't cover a part of its docking tongue and
- // there is a space between a dockable floater and a control to which it is docked.
- if (use_tongue && dockableRect.getHeight() >= max_available_height)
- {
- dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(), max_available_height);
- mDockableFloater->reshape(dockableRect.getWidth(), dockableRect.getHeight());
- }
- else
- {
- // move dockable
- dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
- dockableRect.getHeight());
- }
- LLRect localDocableParentRect;
- mDockableFloater->getParent()->screenRectToLocal(dockableRect,
- &localDocableParentRect);
- mDockableFloater->setRect(localDocableParentRect);
-
- mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
- &mDockTongueX, &mDockTongueY);
-
-}
-
-void LLDockControl::on()
-{
- if (isDockVisible())
- {
- mEnabled = true;
- mRecalculateDocablePosition = true;
- }
-}
-
-void LLDockControl::off()
-{
- mEnabled = false;
-}
-
-void LLDockControl::forceRecalculatePosition()
-{
- mRecalculateDocablePosition = true;
-}
-
-void LLDockControl::drawToungue()
-{
- bool use_tongue = false;
- LLDockableFloater* dockable_floater =
- dynamic_cast<LLDockableFloater*> (mDockableFloater);
- if (dockable_floater != NULL)
- {
- use_tongue = dockable_floater->getUseTongue();
- }
-
- if (mEnabled && use_tongue)
- {
- mDockTongue->draw(mDockTongueX, mDockTongueY);
- }
-}
-
+/**
+ * @file lldockcontrol.cpp
+ * @brief Creates a panel of a specific kind for a toast
+ *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "lldockcontrol.h"
+#include "lldockablefloater.h"
+
+LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
+ const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) :
+ mDockWidget(dockWidget),
+ mDockableFloater(dockableFloater),
+ mDockTongue(dockTongue),
+ mDockTongueX(0),
+ mDockTongueY(0)
+{
+ mDockAt = dockAt;
+
+ if (dockableFloater->isDocked())
+ {
+ on();
+ }
+ else
+ {
+ off();
+ }
+
+ if (!(get_allowed_rect_callback))
+ {
+ mGetAllowedRectCallback = boost::bind(&LLDockControl::getAllowedRect, this, _1);
+ }
+ else
+ {
+ mGetAllowedRectCallback = get_allowed_rect_callback;
+ }
+
+ if (dockWidget != NULL)
+ {
+ repositionDockable();
+ }
+
+ if (mDockWidget != NULL)
+ {
+ mDockWidgetVisible = isDockVisible();
+ }
+ else
+ {
+ mDockWidgetVisible = false;
+ }
+}
+
+LLDockControl::~LLDockControl()
+{
+}
+
+void LLDockControl::setDock(LLView* dockWidget)
+{
+ mDockWidget = dockWidget;
+ if (mDockWidget != NULL)
+ {
+ repositionDockable();
+ mDockWidgetVisible = isDockVisible();
+ }
+ else
+ {
+ mDockWidgetVisible = false;
+ }
+}
+
+void LLDockControl::getAllowedRect(LLRect& rect)
+{
+ rect = mDockableFloater->getRootView()->getRect();
+}
+
+void LLDockControl::repositionDockable()
+{
+ LLRect dockRect = mDockWidget->calcScreenRect();
+ LLRect rootRect;
+ 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)
+ {
+ // undock dockable and off() if dock not visible
+ if (!isDockVisible())
+ {
+ mDockableFloater->setDocked(false);
+ // force off() since dockable may not have dockControll at this time
+ off();
+ LLDockableFloater* dockable_floater =
+ dynamic_cast<LLDockableFloater*> (mDockableFloater);
+ if(dockable_floater != NULL)
+ {
+ dockable_floater->onDockHidden();
+ }
+ }
+ else
+ {
+ if(mEnabled)
+ {
+ moveDockable();
+ }
+ LLDockableFloater* dockable_floater =
+ dynamic_cast<LLDockableFloater*> (mDockableFloater);
+ if(dockable_floater != NULL)
+ {
+ dockable_floater->onDockShown();
+ }
+ }
+
+ mPrevDockRect = dockRect;
+ mRootRect = rootRect;
+ mRecalculateDocablePosition = false;
+ mDockWidgetVisible = isDockVisible();
+ }
+}
+
+bool LLDockControl::isDockVisible()
+{
+ bool res = true;
+
+ if (mDockWidget != NULL)
+ {
+ //we should check all hierarchy
+ res = mDockWidget->isInVisibleChain();
+ if (res)
+ {
+ LLRect dockRect = mDockWidget->calcScreenRect();
+
+ switch (mDockAt)
+ {
+ case LEFT: // to keep compiler happy
+ break;
+ case BOTTOM:
+ case TOP:
+ {
+ // check is dock inside parent rect
+ // assume that parent for all dockable flaoters
+ // is the root view
+ LLRect dockParentRect =
+ mDockWidget->getRootView()->calcScreenRect();
+ if (dockRect.mRight <= dockParentRect.mLeft
+ || dockRect.mLeft >= dockParentRect.mRight)
+ {
+ res = false;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+
+ return res;
+}
+
+void LLDockControl::moveDockable()
+{
+ // calculate new dockable position
+ LLRect dockRect = mDockWidget->calcScreenRect();
+ LLRect rootRect;
+ mGetAllowedRectCallback(rootRect);
+
+ bool use_tongue = false;
+ LLDockableFloater* dockable_floater =
+ dynamic_cast<LLDockableFloater*> (mDockableFloater);
+ if (dockable_floater != NULL)
+ {
+ use_tongue = dockable_floater->getUseTongue();
+ }
+
+ LLRect dockableRect = mDockableFloater->calcScreenRect();
+ S32 x = 0;
+ S32 y = 0;
+ LLRect dockParentRect;
+ 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 = rootRect.mLeft;
+ }
+ if (x + dockableRect.getWidth() > rootRect.mRight)
+ {
+ x = rootRect.mRight - dockableRect.getWidth();
+ }
+
+ mDockTongueX = x + dockableRect.getWidth()/2 - mDockTongue->getWidth() / 2;
+
+ mDockTongueY = dockRect.mTop;
+ break;
+
+ case TOP:
+ x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
+ y = dockRect.mTop + dockableRect.getHeight();
+ // unique docking used with dock tongue, so add tongue height to the Y coordinate
+ if (use_tongue)
+ {
+ y += mDockTongue->getHeight();
+
+ if ( y > rootRect.mTop)
+ {
+ y = rootRect.mTop;
+ }
+ }
+
+ // check is dockable inside root view rect
+ if (x < rootRect.mLeft)
+ {
+ x = rootRect.mLeft;
+ }
+ if (x + dockableRect.getWidth() > rootRect.mRight)
+ {
+ x = rootRect.mRight - dockableRect.getWidth();
+ }
+
+
+ // calculate dock tongue position
+ dockParentRect = mDockWidget->getParent()->calcScreenRect();
+ if (dockRect.getCenterX() < dockParentRect.mLeft)
+ {
+ mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
+ }
+ else if (dockRect.getCenterX() > dockParentRect.mRight)
+ {
+ mDockTongueX = dockParentRect.mRight - mDockTongue->getWidth() / 2;;
+ }
+ else
+ {
+ mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
+ }
+ mDockTongueY = dockRect.mTop;
+
+ break;
+ case BOTTOM:
+ x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
+ y = dockRect.mBottom;
+ // unique docking used with dock tongue, so add tongue height to the Y coordinate
+ if (use_tongue)
+ {
+ y -= mDockTongue->getHeight();
+ }
+
+ // check is dockable inside root view rect
+ if (x < rootRect.mLeft)
+ {
+ x = rootRect.mLeft;
+ }
+ if (x + dockableRect.getWidth() > rootRect.mRight)
+ {
+ x = rootRect.mRight - dockableRect.getWidth();
+ }
+
+ // calculate dock tongue position
+ dockParentRect = mDockWidget->getParent()->calcScreenRect();
+ if (dockRect.getCenterX() < dockParentRect.mLeft)
+ {
+ mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
+ }
+ else if (dockRect.getCenterX() > dockParentRect.mRight)
+ {
+ mDockTongueX = dockParentRect.mRight - mDockTongue->getWidth() / 2;;
+ }
+ else
+ {
+ mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
+ }
+ mDockTongueY = dockRect.mBottom - mDockTongue->getHeight();
+
+ break;
+ }
+
+ S32 max_available_height = rootRect.getHeight() - (rootRect.mBottom - mDockTongueY) - mDockTongue->getHeight();
+
+ // A floater should be shrunk so it doesn't cover a part of its docking tongue and
+ // there is a space between a dockable floater and a control to which it is docked.
+ if (use_tongue && dockableRect.getHeight() >= max_available_height)
+ {
+ dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(), max_available_height);
+ mDockableFloater->reshape(dockableRect.getWidth(), dockableRect.getHeight());
+ }
+ else
+ {
+ // move dockable
+ dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
+ dockableRect.getHeight());
+ }
+ LLRect localDocableParentRect;
+ mDockableFloater->getParent()->screenRectToLocal(dockableRect,
+ &localDocableParentRect);
+ mDockableFloater->setRect(localDocableParentRect);
+
+ mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
+ &mDockTongueX, &mDockTongueY);
+
+}
+
+void LLDockControl::on()
+{
+ if (isDockVisible())
+ {
+ mEnabled = true;
+ mRecalculateDocablePosition = true;
+ }
+}
+
+void LLDockControl::off()
+{
+ mEnabled = false;
+}
+
+void LLDockControl::forceRecalculatePosition()
+{
+ mRecalculateDocablePosition = true;
+}
+
+void LLDockControl::drawToungue()
+{
+ bool use_tongue = false;
+ LLDockableFloater* dockable_floater =
+ dynamic_cast<LLDockableFloater*> (mDockableFloater);
+ if (dockable_floater != NULL)
+ {
+ use_tongue = dockable_floater->getUseTongue();
+ }
+
+ if (mEnabled && use_tongue)
+ {
+ mDockTongue->draw(mDockTongueX, mDockTongueY);
+ }
+}
+
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 19ac4c58a8..9b6830a816 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -563,7 +563,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
}
// update resize bars with new limits
- LLResizeBar* last_resize_bar = NULL;
+ LLLayoutPanel* last_resizeable_panel = NULL;
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
LLPanel* panelp = (*panel_it);
@@ -585,17 +585,17 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
BOOL resize_bar_enabled = panelp->getVisible() && (*panel_it)->mUserResize;
(*panel_it)->mResizeBar->setVisible(resize_bar_enabled);
- if (resize_bar_enabled)
+ if ((*panel_it)->mUserResize || (*panel_it)->mAutoResize)
{
- last_resize_bar = (*panel_it)->mResizeBar;
+ last_resizeable_panel = (*panel_it);
}
}
// hide last resize bar as there is nothing past it
// resize bars need to be in between two resizable panels
- if (last_resize_bar)
+ if (last_resizeable_panel)
{
- last_resize_bar->setVisible(FALSE);
+ last_resizeable_panel->mResizeBar->setVisible(FALSE);
}
// not enough room to fit existing contents
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 89614e6d12..bdac125eb0 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -1195,16 +1195,18 @@ bool LLNotifications::uniqueFilter(LLNotificationPtr pNotif)
bool LLNotifications::uniqueHandler(const LLSD& payload)
{
+ std::string cmd = payload["sigtype"];
+
LLNotificationPtr pNotif = LLNotifications::instance().find(payload["id"].asUUID());
if (pNotif && pNotif->hasUniquenessConstraints())
{
- if (payload["sigtype"].asString() == "add")
+ if (cmd == "add")
{
// not a duplicate according to uniqueness criteria, so we keep it
// and store it for future uniqueness checks
mUniqueNotifications.insert(std::make_pair(pNotif->getName(), pNotif));
}
- else if (payload["sigtype"].asString() == "delete")
+ else if (cmd == "delete")
{
mUniqueNotifications.erase(pNotif->getName());
}
@@ -1217,7 +1219,9 @@ bool LLNotifications::failedUniquenessTest(const LLSD& payload)
{
LLNotificationPtr pNotif = LLNotifications::instance().find(payload["id"].asUUID());
- if (!pNotif)
+ std::string cmd = payload["sigtype"];
+
+ if (!pNotif || cmd != "add")
{
return false;
}
@@ -1310,17 +1314,6 @@ void LLNotifications::createDefaultChannels()
connectFailedFilter(&visibilityRuleMached);
}
-bool LLNotifications::addTemplate(const std::string &name,
- LLNotificationTemplatePtr theTemplate)
-{
- if (mTemplates.count(name))
- {
- llwarns << "LLNotifications -- attempted to add template '" << name << "' twice." << llendl;
- return false;
- }
- mTemplates[name] = theTemplate;
- return true;
-}
LLNotificationTemplatePtr LLNotifications::getTemplate(const std::string& name)
{
@@ -1417,27 +1410,45 @@ void replaceFormText(LLNotificationForm::Params& form, const std::string& patter
}
}
+void addPathIfExists(const std::string& new_path, std::vector<std::string>& paths)
+{
+ if (gDirUtilp->fileExists(new_path))
+ {
+ paths.push_back(new_path);
+ }
+}
+
bool LLNotifications::loadTemplates()
{
- const std::string xml_filename = "notifications.xml";
- std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getXUIPaths().front(), xml_filename);
+ std::vector<std::string> search_paths;
+
+ std::string skin_relative_path = gDirUtilp->getDirDelimiter() + LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + "notifications.xml";
+ std::string localized_skin_relative_path = gDirUtilp->getDirDelimiter() + LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + "notifications.xml";
+
+ addPathIfExists(gDirUtilp->getDefaultSkinDir() + skin_relative_path, search_paths);
+ addPathIfExists(gDirUtilp->getDefaultSkinDir() + localized_skin_relative_path, search_paths);
+ addPathIfExists(gDirUtilp->getSkinDir() + skin_relative_path, search_paths);
+ addPathIfExists(gDirUtilp->getSkinDir() + localized_skin_relative_path, search_paths);
+ addPathIfExists(gDirUtilp->getUserSkinDir() + skin_relative_path, search_paths);
+ addPathIfExists(gDirUtilp->getUserSkinDir() + localized_skin_relative_path, search_paths);
+ std::string base_filename = search_paths.front();
LLXMLNodePtr root;
- BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
+ BOOL success = LLXMLNode::getLayeredXMLNode(root, search_paths);
if (!success || root.isNull() || !root->hasName( "notifications" ))
{
- llerrs << "Problem reading UI Notifications file: " << full_filename << llendl;
+ llerrs << "Problem reading UI Notifications file: " << base_filename << llendl;
return false;
}
LLNotificationTemplate::Notifications params;
LLXUIParser parser;
- parser.readXUI(root, params, full_filename);
+ parser.readXUI(root, params, base_filename);
if(!params.validateBlock())
{
- llerrs << "Problem reading UI Notifications file: " << full_filename << llendl;
+ llerrs << "Problem reading UI Notifications file: " << base_filename << llendl;
return false;
}
@@ -1484,7 +1495,7 @@ bool LLNotifications::loadTemplates()
replaceFormText(it->form_ref.form, "$ignoretext", it->form_ref.form_template.ignore_text);
}
}
- addTemplate(it->name, LLNotificationTemplatePtr(new LLNotificationTemplate(*it)));
+ mTemplates[it->name] = LLNotificationTemplatePtr(new LLNotificationTemplate(*it));
}
return true;
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 34d3537781..0c4d4fc897 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -863,10 +863,11 @@ class LLNotifications :
friend class LLSingleton<LLNotifications>;
public:
- // load notification descriptions from file;
- // OK to call more than once because it will reload
- bool loadTemplates();
-
+ // load all notification descriptions from file
+ // calling more than once will overwrite existing templates
+ // but never delete a template
+ bool loadTemplates();
+
// load visibility rules from file;
// OK to call more than once because it will reload
bool loadVisibilityRules();
@@ -950,8 +951,6 @@ private:
LLNotificationChannelPtr pHistoryChannel;
LLNotificationChannelPtr pExpirationChannel;
- // put your template in
- bool addTemplate(const std::string& name, LLNotificationTemplatePtr theTemplate);
TemplateMap mTemplates;
VisibilityRuleList mVisibilityRules;
diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index 55b32fc8b1..25e7a31e90 100644
--- a/indra/llui/lluictrlfactory.cpp
+++ b/indra/llui/lluictrlfactory.cpp
@@ -152,7 +152,27 @@ static LLFastTimer::DeclareTimer FTM_XML_PARSE("XML Reading/Parsing");
bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root)
{
LLFastTimer timer(FTM_XML_PARSE);
- return LLXMLNode::getLayeredXMLNode(xui_filename, root, LLUI::getXUIPaths());
+
+ std::vector<std::string> paths;
+ std::string path = gDirUtilp->findSkinnedFilename(LLUI::getSkinPath(), xui_filename);
+ if (!path.empty())
+ {
+ paths.push_back(path);
+ }
+
+ std::string localize_path = gDirUtilp->findSkinnedFilename(LLUI::getLocalizedSkinPath(), xui_filename);
+ if (!localize_path.empty() && localize_path != path)
+ {
+ paths.push_back(localize_path);
+ }
+
+ if (paths.empty())
+ {
+ // sometimes whole path is passed in as filename
+ paths.push_back(xui_filename);
+ }
+
+ return LLXMLNode::getLayeredXMLNode(root, paths);
}
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index acf7953906..d73e87129e 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -338,7 +338,7 @@ void LLView::removeChild(LLView* child)
}
else
{
- llerrs << "LLView::removeChild called with non-child" << llendl;
+ llwarns << child->getName() << "is not a child of " << getName() << llendl;
}
updateBoundingRect();
}