summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/CMakeLists.txt7
-rw-r--r--indra/llui/llbutton.cpp51
-rw-r--r--indra/llui/llbutton.h22
-rw-r--r--indra/llui/llclipboard.cpp6
-rw-r--r--indra/llui/llclipboard.h9
-rw-r--r--indra/llui/llcommandmanager.cpp182
-rw-r--r--indra/llui/llcommandmanager.h199
-rw-r--r--indra/llui/lldockcontrol.cpp3
-rw-r--r--indra/llui/llfloater.h2
-rw-r--r--indra/llui/llfloaterreg.cpp41
-rw-r--r--indra/llui/llfloaterreg.h1
-rw-r--r--indra/llui/lllayoutstack.cpp244
-rw-r--r--indra/llui/lllayoutstack.h28
-rw-r--r--indra/llui/lllineeditor.h2
-rw-r--r--indra/llui/llloadingindicator.cpp7
-rw-r--r--indra/llui/llloadingindicator.h4
-rw-r--r--indra/llui/llmenugl.cpp2
-rw-r--r--indra/llui/llnotifications.h4
-rw-r--r--indra/llui/llnotificationtemplate.h4
-rw-r--r--indra/llui/llnotificationvisibilityrule.h2
-rw-r--r--indra/llui/llpanel.h3
-rw-r--r--indra/llui/llresizehandle.cpp12
-rw-r--r--indra/llui/llresizehandle.h5
-rw-r--r--indra/llui/llscrolllistcolumn.h4
-rw-r--r--indra/llui/llsdparam.cpp6
-rw-r--r--indra/llui/llsdparam.h4
-rw-r--r--indra/llui/lltextbase.h2
-rw-r--r--indra/llui/lltoolbar.cpp682
-rw-r--r--indra/llui/lltoolbar.h218
-rw-r--r--indra/llui/llui.cpp11
-rw-r--r--indra/llui/llui.h119
-rw-r--r--indra/llui/lluicolortable.h2
-rw-r--r--indra/llui/lluictrl.cpp10
-rw-r--r--indra/llui/lluictrl.h7
-rw-r--r--indra/llui/lluictrlfactory.h10
-rw-r--r--indra/llui/llview.cpp7
-rw-r--r--indra/llui/llview.h23
37 files changed, 1704 insertions, 241 deletions
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index b3b2f4ae56..dded8ab661 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -5,6 +5,7 @@ project(llui)
include(00-Common)
include(LLCommon)
include(LLImage)
+include(LLInventory)
include(LLMath)
include(LLMessage)
include(LLRender)
@@ -16,6 +17,7 @@ include(LLXUIXML)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLIMAGE_INCLUDE_DIRS}
+ ${LLINVENTORY_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
${LLRENDER_INCLUDE_DIRS}
@@ -35,6 +37,7 @@ set(llui_SOURCE_FILES
llcheckboxctrl.cpp
llclipboard.cpp
llcombobox.cpp
+ llcommandmanager.cpp
llconsole.cpp
llcontainerview.cpp
llctrlselectioninterface.cpp
@@ -99,6 +102,7 @@ set(llui_SOURCE_FILES
lltimectrl.cpp
lltransutil.cpp
lltoggleablemenu.cpp
+ lltoolbar.cpp
lltooltip.cpp
llui.cpp
lluicolortable.cpp
@@ -131,6 +135,7 @@ set(llui_HEADER_FILES
llcheckboxctrl.h
llclipboard.h
llcombobox.h
+ llcommandmanager.h
llconsole.h
llcontainerview.h
llctrlselectioninterface.h
@@ -200,6 +205,7 @@ set(llui_HEADER_FILES
lltextvalidate.h
lltimectrl.h
lltoggleablemenu.h
+ lltoolbar.h
lltooltip.h
lltransutil.h
lluicolortable.h
@@ -245,6 +251,7 @@ target_link_libraries(llui
${LLRENDER_LIBRARIES}
${LLWINDOW_LIBRARIES}
${LLIMAGE_LIBRARIES}
+ ${LLINVENTORY_LIBRARIES}
${LLVFS_LIBRARIES} # ugh, just for LLDir
${LLXUIXML_LIBRARIES}
${LLXML_LIBRARIES}
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 2459429f6e..f259e8027e 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -314,7 +314,7 @@ boost::signals2::connection LLButton::setHeldDownCallback( const commit_signal_t
}
-// *TODO: Deprecate (for backwards compatability only)
+// *TODO: Deprecate (for backwards compatibility only)
boost::signals2::connection LLButton::setClickedCallback( button_callback_t cb, void* data )
{
return setClickedCallback(boost::bind(cb, data));
@@ -554,6 +554,16 @@ BOOL LLButton::handleHover(S32 x, S32 y, MASK mask)
return TRUE;
}
+void LLButton::getOverlayImageSize(S32& overlay_width, S32& overlay_height)
+{
+ overlay_width = mImageOverlay->getWidth();
+ overlay_height = mImageOverlay->getHeight();
+
+ F32 scale_factor = llmin((F32)getRect().getWidth() / (F32)overlay_width, (F32)getRect().getHeight() / (F32)overlay_height, 1.f);
+ overlay_width = llround((F32)overlay_width * scale_factor);
+ overlay_height = llround((F32)overlay_height * scale_factor);
+}
+
// virtual
void LLButton::draw()
@@ -781,12 +791,10 @@ void LLButton::draw()
if (mImageOverlay.notNull())
{
// get max width and height (discard level 0)
- S32 overlay_width = mImageOverlay->getWidth();
- S32 overlay_height = mImageOverlay->getHeight();
+ S32 overlay_width;
+ S32 overlay_height;
- F32 scale_factor = llmin((F32)getRect().getWidth() / (F32)overlay_width, (F32)getRect().getHeight() / (F32)overlay_height, 1.f);
- overlay_width = llround((F32)overlay_width * scale_factor);
- overlay_height = llround((F32)overlay_height * scale_factor);
+ getOverlayImageSize(overlay_width, overlay_height);
S32 center_x = getLocalRect().getCenterX();
S32 center_y = getLocalRect().getCenterY();
@@ -811,6 +819,7 @@ void LLButton::draw()
{
case LLFontGL::LEFT:
text_left += overlay_width + mImgOverlayLabelSpace;
+ text_width -= overlay_width + mImgOverlayLabelSpace;
mImageOverlay->draw(
mLeftHPad,
center_y - (overlay_height / 2),
@@ -828,6 +837,7 @@ void LLButton::draw()
break;
case LLFontGL::RIGHT:
text_right -= overlay_width + mImgOverlayLabelSpace;
+ text_width -= overlay_width + mImgOverlayLabelSpace;
mImageOverlay->draw(
getRect().getWidth() - mRightHPad - overlay_width,
center_y - (overlay_height / 2),
@@ -919,7 +929,7 @@ void LLButton::setToggleState(BOOL b)
void LLButton::setFlashing( BOOL b )
{
- if (b != mFlashing)
+ if ((bool)b != mFlashing)
{
mFlashing = b;
mFlashingTimer.reset();
@@ -989,11 +999,32 @@ void LLButton::resize(LLUIString label)
// get current btn length
S32 btn_width =getRect().getWidth();
// check if it need resize
- if (mAutoResize == TRUE)
+ if (mAutoResize)
{
- if (btn_width - (mRightHPad + mLeftHPad) < label_width)
+ S32 min_width = label_width + mLeftHPad + mRightHPad;
+ if (mImageOverlay)
+ {
+ S32 overlay_width = mImageOverlay->getWidth();
+ F32 scale_factor = getRect().getHeight() / (F32)mImageOverlay->getHeight();
+ overlay_width = llround((F32)overlay_width * scale_factor);
+
+ switch(mImageOverlayAlignment)
+ {
+ case LLFontGL::LEFT:
+ case LLFontGL::RIGHT:
+ min_width += overlay_width + mImgOverlayLabelSpace;
+ break;
+ case LLFontGL::HCENTER:
+ min_width = llmax(min_width, overlay_width + mLeftHPad + mRightHPad);
+ break;
+ default:
+ // draw nothing
+ break;
+ }
+ }
+ if (btn_width < min_width)
{
- setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mLeft + label_width + mLeftHPad + mRightHPad , getRect().mBottom));
+ reshape(min_width, getRect().getHeight());
}
}
}
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 5968916006..08b45e01b3 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -270,6 +270,7 @@ public:
protected:
LLPointer<LLUIImage> getImageUnselected() const { return mImageUnselected; }
LLPointer<LLUIImage> getImageSelected() const { return mImageSelected; }
+ void getOverlayImageSize(S32& overlay_width, S32& overlay_height);
LLFrameTimer mMouseDownTimer;
@@ -327,15 +328,14 @@ private:
LLUIColor mImageColor;
LLUIColor mDisabledImageColor;
- BOOL mIsToggle;
- BOOL mScaleImage;
+ bool mIsToggle;
+ bool mScaleImage;
- BOOL mDropShadowedText;
- BOOL mAutoResize;
- BOOL mUseEllipses;
- BOOL mBorderEnabled;
-
- BOOL mFlashing;
+ bool mDropShadowedText;
+ bool mAutoResize;
+ bool mUseEllipses;
+ bool mBorderEnabled;
+ bool mFlashing;
LLFontGL::HAlign mHAlign;
S32 mLeftHPad;
@@ -355,9 +355,9 @@ private:
F32 mHoverGlowStrength;
F32 mCurGlowStrength;
- BOOL mNeedsHighlight;
- BOOL mCommitOnReturn;
- BOOL mFadeWhenDisabled;
+ bool mNeedsHighlight;
+ bool mCommitOnReturn;
+ bool mFadeWhenDisabled;
bool mForcePressedState;
LLFrameTimer mFlashingTimer;
diff --git a/indra/llui/llclipboard.cpp b/indra/llui/llclipboard.cpp
index 984c4ec5fb..6910b962a1 100644
--- a/indra/llui/llclipboard.cpp
+++ b/indra/llui/llclipboard.cpp
@@ -40,6 +40,7 @@ LLClipboard gClipboard;
LLClipboard::LLClipboard()
{
+ mSourceItem = NULL;
}
@@ -134,3 +135,8 @@ BOOL LLClipboard::canPastePrimaryString() const
{
return LLView::getWindow()->isPrimaryTextAvailable();
}
+
+void LLClipboard::setSourceObject(const LLUUID& source_id, LLAssetType::EType type)
+{
+ mSourceItem = new LLInventoryObject (source_id, LLUUID::null, type, "");
+}
diff --git a/indra/llui/llclipboard.h b/indra/llui/llclipboard.h
index 24cb46c3f4..9371b94284 100644
--- a/indra/llui/llclipboard.h
+++ b/indra/llui/llclipboard.h
@@ -30,6 +30,8 @@
#include "llstring.h"
#include "lluuid.h"
+#include "stdenums.h"
+#include "llinventory.h"
class LLClipboard
@@ -52,9 +54,14 @@ public:
BOOL canPastePrimaryString() const;
const LLWString& getPastePrimaryWString(LLUUID* source_id = NULL);
+ // Support clipboard for object known only by their uuid and asset type
+ void setSourceObject(const LLUUID& source_id, LLAssetType::EType type);
+ const LLInventoryObject* getSourceObject() { return mSourceItem; }
+
private:
- LLUUID mSourceID;
+ LLUUID mSourceID;
LLWString mString;
+ LLInventoryObject* mSourceItem;
};
diff --git a/indra/llui/llcommandmanager.cpp b/indra/llui/llcommandmanager.cpp
new file mode 100644
index 0000000000..2bd50af7af
--- /dev/null
+++ b/indra/llui/llcommandmanager.cpp
@@ -0,0 +1,182 @@
+/**
+ * @file llcommandmanager.cpp
+ * @brief LLCommandManager class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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$
+ */
+
+// A control that displays the name of the chosen item, which when
+// clicked shows a scrolling box of options.
+
+#include "linden_common.h"
+
+#include "llcommandmanager.h"
+#include "lldir.h"
+#include "llerror.h"
+#include "llxuiparser.h"
+
+#include <boost/foreach.hpp>
+
+
+//
+// LLCommandId class
+//
+
+const LLCommandId LLCommandId::null("null command");
+
+//
+// LLCommand class
+//
+
+LLCommand::Params::Params()
+ : available_in_toybox("available_in_toybox", false)
+ , icon("icon")
+ , label_ref("label_ref")
+ , name("name")
+ , tooltip_ref("tooltip_ref")
+ , execute_function("execute_function")
+ , execute_parameters("execute_parameters")
+ , is_enabled_function("is_enabled_function")
+ , is_enabled_parameters("is_enabled_parameters")
+ , is_running_function("is_running_function")
+ , is_running_parameters("is_running_parameters")
+ , is_starting_function("is_starting_function")
+ , is_starting_parameters("is_starting_parameters")
+{
+}
+
+LLCommand::LLCommand(const LLCommand::Params& p)
+ : mAvailableInToybox(p.available_in_toybox)
+ , mIcon(p.icon)
+ , mIdentifier(p.name)
+ , mLabelRef(p.label_ref)
+ , mTooltipRef(p.tooltip_ref)
+ , mExecuteFunction(p.execute_function)
+ , mExecuteParameters(p.execute_parameters)
+ , mIsEnabledFunction(p.is_enabled_function)
+ , mIsEnabledParameters(p.is_enabled_parameters)
+ , mIsRunningFunction(p.is_running_function)
+ , mIsRunningParameters(p.is_running_parameters)
+ , mIsStartingFunction(p.is_starting_function)
+ , mIsStartingParameters(p.is_starting_parameters)
+{
+}
+
+
+//
+// LLCommandManager class
+//
+
+LLCommandManager::LLCommandManager()
+{
+}
+
+LLCommandManager::~LLCommandManager()
+{
+ for (CommandVector::iterator cmdIt = mCommands.begin(); cmdIt != mCommands.end(); ++cmdIt)
+ {
+ LLCommand * command = *cmdIt;
+
+ delete command;
+ }
+}
+
+U32 LLCommandManager::commandCount() const
+{
+ return mCommands.size();
+}
+
+LLCommand * LLCommandManager::getCommand(U32 commandIndex)
+{
+ return mCommands[commandIndex];
+}
+
+LLCommand * LLCommandManager::getCommand(const LLCommandId& commandId)
+{
+ LLCommand * command_match = NULL;
+
+ CommandIndexMap::const_iterator found = mCommandIndices.find(commandId);
+
+ if (found != mCommandIndices.end())
+ {
+ command_match = mCommands[found->second];
+ }
+
+ return command_match;
+}
+
+LLCommand * LLCommandManager::getCommand(const LLUUID& commandUUID)
+{
+ LLCommand * command_match = NULL;
+
+ CommandUUIDMap::const_iterator found = mCommandUUIDs.find(commandUUID);
+
+ if (found != mCommandUUIDs.end())
+ {
+ command_match = mCommands[found->second];
+ }
+
+ return command_match;
+}
+
+void LLCommandManager::addCommand(LLCommand * command)
+{
+ LLCommandId command_id = command->id();
+ mCommandIndices[command_id] = mCommands.size();
+ mCommandUUIDs[command_id.uuid()] = mCommands.size();
+ mCommands.push_back(command);
+
+ lldebugs << "Successfully added command: " << command->id().name() << llendl;
+}
+
+//static
+bool LLCommandManager::load()
+{
+ LLCommandManager& mgr = LLCommandManager::instance();
+
+ std::string commands_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "commands.xml");
+
+ LLCommandManager::Params commandsParams;
+
+ LLSimpleXUIParser parser;
+
+ if (!parser.readXUI(commands_file, commandsParams))
+ {
+ llerrs << "Unable to load xml file: " << commands_file << llendl;
+ return false;
+ }
+
+ if (!commandsParams.validateBlock())
+ {
+ llerrs << "Unable to validate commands param block from file: " << commands_file << llendl;
+ return false;
+ }
+
+ BOOST_FOREACH(LLCommand::Params& commandParams, commandsParams.commands)
+ {
+ LLCommand * command = new LLCommand(commandParams);
+
+ mgr.addCommand(command);
+ }
+
+ return true;
+}
diff --git a/indra/llui/llcommandmanager.h b/indra/llui/llcommandmanager.h
new file mode 100644
index 0000000000..b11f905574
--- /dev/null
+++ b/indra/llui/llcommandmanager.h
@@ -0,0 +1,199 @@
+/**
+ * @file llcommandmanager.h
+ * @brief LLCommandManager class to hold commands
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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$
+ */
+
+#ifndef LL_LLCOMMANDMANAGER_H
+#define LL_LLCOMMANDMANAGER_H
+
+#include "llinitparam.h"
+#include "llsingleton.h"
+
+
+class LLCommand;
+class LLCommandManager;
+
+
+class LLCommandId
+{
+public:
+ friend class LLCommand;
+ friend class LLCommandManager;
+
+ struct Params : public LLInitParam::Block<Params>
+ {
+ Mandatory<std::string> name;
+
+ Params()
+ : name("name")
+ {}
+ };
+
+ LLCommandId(const std::string& name)
+ : mName(name)
+ {
+ mUUID = LLUUID::LLUUID::generateNewID(name);
+ }
+
+ LLCommandId(const Params& p)
+ : mName(p.name)
+ {
+ mUUID = LLUUID::LLUUID::generateNewID(p.name);
+ }
+
+ const std::string& name() const { return mName; }
+ const LLUUID& uuid() const { return mUUID; }
+
+ bool operator!=(const LLCommandId& command) const
+ {
+ return (mName != command.mName);
+ }
+
+ bool operator==(const LLCommandId& command) const
+ {
+ return (mName == command.mName);
+ }
+
+ bool operator<(const LLCommandId& command) const
+ {
+ return (mName < command.mName);
+ }
+
+ static const LLCommandId null;
+
+private:
+ std::string mName;
+ LLUUID mUUID;
+};
+
+typedef std::list<LLCommandId> command_id_list_t;
+
+
+class LLCommand
+{
+public:
+ struct Params : public LLInitParam::Block<Params>
+ {
+ Mandatory<bool> available_in_toybox;
+ Mandatory<std::string> icon;
+ Mandatory<std::string> label_ref;
+ Mandatory<std::string> name;
+ Mandatory<std::string> tooltip_ref;
+
+ Mandatory<std::string> execute_function;
+ Optional<LLSD> execute_parameters;
+
+ Optional<std::string> is_enabled_function;
+ Optional<LLSD> is_enabled_parameters;
+
+ Optional<std::string> is_running_function;
+ Optional<LLSD> is_running_parameters;
+
+ Optional<std::string> is_starting_function;
+ Optional<LLSD> is_starting_parameters;
+
+ Params();
+ };
+
+ LLCommand(const LLCommand::Params& p);
+
+ const bool availableInToybox() const { return mAvailableInToybox; }
+ const std::string& icon() const { return mIcon; }
+ const LLCommandId& id() const { return mIdentifier; }
+ const std::string& labelRef() const { return mLabelRef; }
+ const std::string& tooltipRef() const { return mTooltipRef; }
+
+ const std::string& executeFunctionName() const { return mExecuteFunction; }
+ const LLSD& executeParameters() const { return mExecuteParameters; }
+
+ const std::string& isEnabledFunctionName() const { return mIsEnabledFunction; }
+ const LLSD& isEnabledParameters() const { return mIsEnabledParameters; }
+
+ const std::string& isRunningFunctionName() const { return mIsRunningFunction; }
+ const LLSD& isRunningParameters() const { return mIsRunningParameters; }
+
+ const std::string& isStartingFunctionName() const { return mIsStartingFunction; }
+ const LLSD& isStartingParameters() const { return mIsStartingParameters; }
+
+private:
+ LLCommandId mIdentifier;
+
+ bool mAvailableInToybox;
+ std::string mIcon;
+ std::string mLabelRef;
+ std::string mTooltipRef;
+
+ std::string mExecuteFunction;
+ LLSD mExecuteParameters;
+
+ std::string mIsEnabledFunction;
+ LLSD mIsEnabledParameters;
+
+ std::string mIsRunningFunction;
+ LLSD mIsRunningParameters;
+
+ std::string mIsStartingFunction;
+ LLSD mIsStartingParameters;
+};
+
+
+class LLCommandManager
+: public LLSingleton<LLCommandManager>
+{
+public:
+ struct Params : public LLInitParam::Block<Params>
+ {
+ Multiple< LLCommand::Params, AtLeast<1> > commands;
+
+ Params()
+ : commands("command")
+ {
+ }
+ };
+
+ LLCommandManager();
+ ~LLCommandManager();
+
+ U32 commandCount() const;
+ LLCommand * getCommand(U32 commandIndex);
+ LLCommand * getCommand(const LLCommandId& commandId);
+ LLCommand * getCommand(const LLUUID& commandUUID);
+
+ static bool load();
+
+protected:
+ void addCommand(LLCommand * command);
+
+private:
+ typedef std::map<LLUUID, U32> CommandUUIDMap;
+ typedef std::map<LLCommandId, U32> CommandIndexMap;
+ typedef std::vector<LLCommand *> CommandVector;
+
+ CommandVector mCommands;
+ CommandIndexMap mCommandIndices;
+ CommandUUIDMap mCommandUUIDs;
+};
+
+
+#endif // LL_LLCOMMANDMANAGER_H
diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index b1c27126d9..6e39fcd714 100644
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -97,6 +97,7 @@ void LLDockControl::getAllowedRect(LLRect& rect)
void LLDockControl::repositionDockable()
{
+ if (!mDockWidget) return;
LLRect dockRect = mDockWidget->calcScreenRect();
LLRect rootRect;
mGetAllowedRectCallback(rootRect);
@@ -160,7 +161,7 @@ bool LLDockControl::isDockVisible()
case TOP:
{
// check is dock inside parent rect
- // assume that parent for all dockable flaoters
+ // assume that parent for all dockable floaters
// is the root view
LLRect dockParentRect =
mDockWidget->getRootView()->calcScreenRect();
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 58c2d34253..fba59e82e1 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -293,7 +293,7 @@ public:
protected:
virtual void applySavedVariables();
- void applyRectControl();
+ virtual void applyRectControl();
void applyDockState();
void storeRectControl();
void storeVisibilityControl();
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index fc7dcfcc4e..27e96856b3 100644
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -453,6 +453,47 @@ void LLFloaterReg::toggleFloaterInstance(const LLSD& sdname)
}
//static
+void LLFloaterReg::toggleToolbarFloaterInstance(const LLSD& sdname)
+{
+ //
+ // Floaters controlled by the toolbar behave a bit differently from others.
+ // Namely they have 3-4 states as defined in the design wiki page here:
+ // https://wiki.lindenlab.com/wiki/FUI_Button_states
+ //
+ // The basic idea is this:
+ // * If the target floater is minimized, this button press will un-minimize it.
+ // * Else if the target floater is closed open it.
+ // * Else if the target floater does not have focus, give it focus.
+ // * Also, if it is not on top, bring it forward when focus is given.
+ // * Else the target floater is open, close it.
+ //
+
+ // First parse the parameter
+ LLSD key;
+ std::string name = sdname.asString();
+ parse_name_key(name, key);
+
+ LLFloater* instance = findInstance(name, key);
+
+ if (LLFloater::isMinimized(instance))
+ {
+ instance->setMinimized(FALSE);
+ }
+ else if (!LLFloater::isShown(instance))
+ {
+ showInstance(name, key, TRUE);
+ }
+ else if (!instance->hasFocus() && !instance->getIsChrome())
+ {
+ instance->setFocus(TRUE);
+ }
+ else
+ {
+ instance->closeFloater();
+ }
+}
+
+//static
bool LLFloaterReg::floaterInstanceVisible(const LLSD& sdname)
{
LLSD key;
diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h
index a2027a77a0..6239d98a7d 100644
--- a/indra/llui/llfloaterreg.h
+++ b/indra/llui/llfloaterreg.h
@@ -127,6 +127,7 @@ public:
static void showFloaterInstance(const LLSD& sdname);
static void hideFloaterInstance(const LLSD& sdname);
static void toggleFloaterInstance(const LLSD& sdname);
+ static void toggleToolbarFloaterInstance(const LLSD& sdname);
static bool floaterInstanceVisible(const LLSD& sdname);
static bool floaterInstanceMinimized(const LLSD& sdname);
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index a250404292..4991c4afa6 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -58,7 +58,9 @@ LLLayoutPanel::LLLayoutPanel(const Params& p)
mCollapsed(FALSE),
mCollapseAmt(0.f),
mVisibleAmt(1.f), // default to fully visible
- mResizeBar(NULL)
+ mResizeBar(NULL),
+ mFractionalSize(0.f),
+ mOrientation(LLLayoutStack::HORIZONTAL)
{
// Set the expanded min dim if it is provided, otherwise it gets the p.min_dim value
if (p.expanded_min_dim.isProvided())
@@ -88,9 +90,22 @@ LLLayoutPanel::~LLLayoutPanel()
mResizeBar = NULL;
}
-F32 LLLayoutPanel::getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation)
+void LLLayoutPanel::reshape(S32 width, S32 height, BOOL called_from_parent)
{
- if (orientation == LLLayoutStack::HORIZONTAL)
+ if (mOrientation == LLLayoutStack::HORIZONTAL)
+ {
+ mFractionalSize += width - llround(mFractionalSize);
+ }
+ else
+ {
+ mFractionalSize += height - llround(mFractionalSize);
+ }
+ LLPanel::reshape(width, height, called_from_parent);
+}
+
+F32 LLLayoutPanel::getCollapseFactor()
+{
+ if (mOrientation == LLLayoutStack::HORIZONTAL)
{
F32 collapse_amt =
clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)getRelevantMinDim() / (F32)llmax(1, getRect().getWidth()));
@@ -149,11 +164,11 @@ void LLLayoutStack::draw()
// scale clipping rectangle by visible amount
if (mOrientation == HORIZONTAL)
{
- clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->getCollapseFactor(mOrientation));
+ clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->getCollapseFactor());
}
else
{
- clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->getCollapseFactor(mOrientation));
+ clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->getCollapseFactor());
}
LLPanel* panelp = (*panel_it);
@@ -193,36 +208,15 @@ bool LLLayoutStack::addChild(LLView* child, S32 tab_group)
LLLayoutPanel* panelp = dynamic_cast<LLLayoutPanel*>(child);
if (panelp)
{
+ panelp->mFractionalSize = (mOrientation == HORIZONTAL)
+ ? panelp->getRect().getWidth()
+ : panelp->getRect().getHeight();
+ panelp->setOrientation(mOrientation);
mPanels.push_back(panelp);
}
return LLView::addChild(child, tab_group);
}
-
-S32 LLLayoutStack::getDefaultHeight(S32 cur_height)
-{
- // if we are spanning our children (crude upward propagation of size)
- // then don't enforce our size on our children
- if (mOrientation == HORIZONTAL)
- {
- cur_height = llmax(mMinHeight, getRect().getHeight());
- }
-
- return cur_height;
-}
-
-S32 LLLayoutStack::getDefaultWidth(S32 cur_width)
-{
- // if we are spanning our children (crude upward propagation of size)
- // then don't enforce our size on our children
- if (mOrientation == VERTICAL)
- {
- cur_width = llmax(mMinWidth, getRect().getWidth());
- }
-
- return cur_width;
-}
-
void LLLayoutStack::movePanel(LLPanel* panel_to_move, LLPanel* target_panel, bool move_to_front)
{
LLLayoutPanel* embedded_panel_to_move = findEmbeddedPanel(panel_to_move);
@@ -317,9 +311,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
createResizeBars();
// calculate current extents
- S32 total_width = 0;
- S32 total_height = 0;
+ F32 total_size = 0.f;
+ //
+ // animate visibility
+ //
e_panel_list_t::iterator panel_it;
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
@@ -361,179 +357,110 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
}
}
- if (panelp->mCollapsed)
- {
- panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, 1.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
- }
- else
- {
- panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, 0.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
- }
+ F32 collapse_state = panelp->mCollapsed ? 1.f : 0.f;
+ panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, collapse_state, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
- if (mOrientation == HORIZONTAL)
- {
- // enforce minimize size constraint by default
- if (panelp->getRect().getWidth() < panelp->getRelevantMinDim())
- {
- panelp->reshape(panelp->getRelevantMinDim(), panelp->getRect().getHeight());
- }
- total_width += llround(panelp->getRect().getWidth() * panelp->getCollapseFactor(mOrientation));
- // want n-1 panel gaps for n panels
- if (panel_it != mPanels.begin())
- {
- total_width += mPanelSpacing;
- }
- }
- else //VERTICAL
+ total_size += panelp->mFractionalSize * panelp->getCollapseFactor();
+ // want n-1 panel gaps for n panels
+ if (panel_it != mPanels.begin())
{
- // enforce minimize size constraint by default
- if (panelp->getRect().getHeight() < panelp->getRelevantMinDim())
- {
- panelp->reshape(panelp->getRect().getWidth(), panelp->getRelevantMinDim());
- }
- total_height += llround(panelp->getRect().getHeight() * panelp->getCollapseFactor(mOrientation));
- if (panel_it != mPanels.begin())
- {
- total_height += mPanelSpacing;
- }
+ total_size += mPanelSpacing;
}
}
S32 num_resizable_panels = 0;
- S32 shrink_headroom_available = 0;
- S32 shrink_headroom_total = 0;
+ F32 shrink_headroom_available = 0.f;
+ F32 shrink_headroom_total = 0.f;
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
+ LLLayoutPanel* panelp = (*panel_it);
+
// panels that are not fully visible do not count towards shrink headroom
- if ((*panel_it)->getCollapseFactor(mOrientation) < 1.f)
+ if (panelp->getCollapseFactor() < 1.f)
{
continue;
}
- S32 relevant_dimension = (mOrientation == HORIZONTAL) ? (*panel_it)->getRect().getWidth() : (*panel_it)->getRect().getHeight();
- S32 relevant_min = (*panel_it)->getRelevantMinDim();
+ F32 cur_size = panelp->mFractionalSize;
+ F32 min_size = (F32)panelp->getRelevantMinDim();
// if currently resizing a panel or the panel is flagged as not automatically resizing
// only track total available headroom, but don't use it for automatic resize logic
- if ((*panel_it)->mResizeBar->hasMouseCapture()
- || (!(*panel_it)->mAutoResize
+ if (panelp->mResizeBar->hasMouseCapture()
+ || (!panelp->mAutoResize
&& !force_resize))
{
- shrink_headroom_total += relevant_dimension - relevant_min;
+ shrink_headroom_total += cur_size - min_size;
}
else
{
num_resizable_panels++;
- shrink_headroom_available += relevant_dimension - relevant_min;
- shrink_headroom_total += relevant_dimension - relevant_min;
+ shrink_headroom_available += cur_size - min_size;
+ shrink_headroom_total += cur_size - min_size;
}
}
// calculate how many pixels need to be distributed among layout panels
// positive means panels need to grow, negative means shrink
- S32 pixels_to_distribute;
- if (mOrientation == HORIZONTAL)
- {
- pixels_to_distribute = getRect().getWidth() - total_width;
- }
- else //VERTICAL
- {
- pixels_to_distribute = getRect().getHeight() - total_height;
- }
+ F32 pixels_to_distribute = (mOrientation == HORIZONTAL)
+ ? getRect().getWidth() - total_size
+ : getRect().getHeight() - total_size;
// now we distribute the pixels...
- S32 cur_x = 0;
- S32 cur_y = getRect().getHeight();
+ F32 cur_x = 0.f;
+ F32 cur_y = (F32)getRect().getHeight();
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
LLLayoutPanel* panelp = (*panel_it);
- S32 cur_width = panelp->getRect().getWidth();
- S32 cur_height = panelp->getRect().getHeight();
- S32 new_width = cur_width;
- S32 new_height = cur_height;
- S32 relevant_min = panelp->getRelevantMinDim();
-
- if (mOrientation == HORIZONTAL)
- {
- new_width = llmax(relevant_min, new_width);
- }
- else
- {
- new_height = llmax(relevant_min, new_height);
- }
- S32 delta_size = 0;
+ F32 min_size = panelp->getRelevantMinDim();
+ F32 delta_size = 0.f;
// if panel can automatically resize (not animating, and resize flag set)...
- if (panelp->getCollapseFactor(mOrientation) == 1.f
+ if (panelp->getCollapseFactor() == 1.f
&& (force_resize || panelp->mAutoResize)
&& !panelp->mResizeBar->hasMouseCapture())
{
- if (mOrientation == HORIZONTAL)
+ if (pixels_to_distribute < 0.f)
{
- // if we're shrinking
- if (pixels_to_distribute < 0)
- {
- // shrink proportionally to amount over minimum
- // so we can do this in one pass
- delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_width - relevant_min) / (F32)shrink_headroom_available)) : 0;
- shrink_headroom_available -= (cur_width - relevant_min);
- }
- else
- {
- // grow all elements equally
- delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels);
- num_resizable_panels--;
- }
- pixels_to_distribute -= delta_size;
- new_width = llmax(relevant_min, cur_width + delta_size);
+ // shrink proportionally to amount over minimum
+ // so we can do this in one pass
+ delta_size = (shrink_headroom_available > 0.f)
+ ? pixels_to_distribute * ((F32)(panelp->mFractionalSize - min_size) / shrink_headroom_available)
+ : 0.f;
+ shrink_headroom_available -= (panelp->mFractionalSize - min_size);
}
else
{
- new_width = getDefaultWidth(new_width);
- }
-
- if (mOrientation == VERTICAL)
- {
- if (pixels_to_distribute < 0)
- {
- // shrink proportionally to amount over minimum
- // so we can do this in one pass
- delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_height - relevant_min) / (F32)shrink_headroom_available)) : 0;
- shrink_headroom_available -= (cur_height - relevant_min);
- }
- else
- {
- delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels);
- num_resizable_panels--;
- }
- pixels_to_distribute -= delta_size;
- new_height = llmax(relevant_min, cur_height + delta_size);
- }
- else
- {
- new_height = getDefaultHeight(new_height);
- }
- }
- else
- {
- if (mOrientation == HORIZONTAL)
- {
- new_height = getDefaultHeight(new_height);
- }
- else // VERTICAL
- {
- new_width = getDefaultWidth(new_width);
+ // grow all elements equally
+ delta_size = pixels_to_distribute / (F32)num_resizable_panels;
+ num_resizable_panels--;
}
+
+ panelp->mFractionalSize = llmax(min_size, panelp->mFractionalSize + delta_size);
+ pixels_to_distribute -= delta_size;
}
// adjust running headroom count based on new sizes
shrink_headroom_total += delta_size;
LLRect panel_rect;
- panel_rect.setLeftTopAndSize(cur_x, cur_y, new_width, new_height);
+ if (mOrientation == HORIZONTAL)
+ {
+ panel_rect.setLeftTopAndSize(llround(cur_x),
+ llround(cur_y),
+ llround(panelp->mFractionalSize),
+ getRect().getHeight());
+ }
+ else
+ {
+ panel_rect.setLeftTopAndSize(llround(cur_x),
+ llround(cur_y),
+ getRect().getWidth(),
+ llround(panelp->mFractionalSize));
+ }
panelp->setShape(panel_rect);
LLRect resize_bar_rect = panel_rect;
@@ -549,13 +476,14 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
}
(*panel_it)->mResizeBar->setRect(resize_bar_rect);
+ F32 size = ((*panel_it)->mFractionalSize * (*panel_it)->getCollapseFactor()) + (F32)mPanelSpacing;
if (mOrientation == HORIZONTAL)
{
- cur_x += llround(new_width * (*panel_it)->getCollapseFactor(mOrientation)) + mPanelSpacing;
+ cur_x += size;
}
else //VERTICAL
{
- cur_y -= llround(new_height * (*panel_it)->getCollapseFactor(mOrientation)) + mPanelSpacing;
+ cur_y -= size;
}
}
@@ -570,13 +498,13 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
{
(*panel_it)->mResizeBar->setResizeLimits(
relevant_min,
- relevant_min + shrink_headroom_total);
+ relevant_min + llround(shrink_headroom_total));
}
else //VERTICAL
{
(*panel_it)->mResizeBar->setResizeLimits(
relevant_min,
- relevant_min + shrink_headroom_total);
+ relevant_min + llround(shrink_headroom_total));
}
// toggle resize bars based on panel visibility, resizability, etc
diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h
index d8ef0aeaca..5d79505fc3 100644
--- a/indra/llui/lllayoutstack.h
+++ b/indra/llui/lllayoutstack.h
@@ -126,8 +126,6 @@ protected:
private:
void createResizeBars();
void calcMinExtents();
- S32 getDefaultHeight(S32 cur_height);
- S32 getDefaultWidth(S32 cur_width);
const ELayoutOrientation mOrientation;
@@ -181,6 +179,8 @@ public:
void initFromParams(const Params& p);
+ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+
S32 getMinDim() const { return mMinDim; }
void setMinDim(S32 value) { mMinDim = value; if (!mExpandedMinDimSpecified) mExpandedMinDim = value; }
@@ -202,22 +202,26 @@ public:
return min_dim;
}
+ void setOrientation(LLLayoutStack::ELayoutOrientation orientation) { mOrientation = orientation; }
+
protected:
LLLayoutPanel(const Params& p);
- F32 getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation);
+ F32 getCollapseFactor();
- bool mExpandedMinDimSpecified;
- S32 mExpandedMinDim;
+ bool mExpandedMinDimSpecified;
+ S32 mExpandedMinDim;
- S32 mMinDim;
- S32 mMaxDim;
- BOOL mAutoResize;
- BOOL mUserResize;
- BOOL mCollapsed;
+ S32 mMinDim;
+ S32 mMaxDim;
+ bool mAutoResize;
+ bool mUserResize;
+ bool mCollapsed;
+ F32 mVisibleAmt;
+ F32 mCollapseAmt;
+ F32 mFractionalSize;
+ LLLayoutStack::ELayoutOrientation mOrientation;
class LLResizeBar* mResizeBar;
- F32 mVisibleAmt;
- F32 mCollapseAmt;
};
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index 583bde360a..2518dbe3c7 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -60,7 +60,7 @@ public:
typedef boost::function<void (LLLineEditor* caller)> keystroke_callback_t;
- struct MaxLength : public LLInitParam::Choice<MaxLength>
+ struct MaxLength : public LLInitParam::ChoiceBlock<MaxLength>
{
Alternative<S32> bytes, chars;
diff --git a/indra/llui/llloadingindicator.cpp b/indra/llui/llloadingindicator.cpp
index c4eec1835c..6ac38f5ad4 100644
--- a/indra/llui/llloadingindicator.cpp
+++ b/indra/llui/llloadingindicator.cpp
@@ -34,6 +34,7 @@
// Project includes
#include "lluictrlfactory.h"
#include "lluiimage.h"
+#include "boost/foreach.hpp"
// registered in llui.cpp to avoid being left out by MS linker
//static LLDefaultChildRegistry::Register<LLLoadingIndicator> r("loading_indicator");
@@ -51,11 +52,9 @@ LLLoadingIndicator::LLLoadingIndicator(const Params& p)
void LLLoadingIndicator::initFromParams(const Params& p)
{
- for (LLInitParam::ParamIterator<LLUIImage*>::const_iterator it = p.images().image.begin(), end_it = p.images().image.end();
- it != end_it;
- ++it)
+ BOOST_FOREACH(LLUIImage* image, p.images.image)
{
- mImages.push_back(it->getValue());
+ mImages.push_back(image);
}
// Start timer for switching images.
diff --git a/indra/llui/llloadingindicator.h b/indra/llui/llloadingindicator.h
index 7c44478848..c1f979c111 100644
--- a/indra/llui/llloadingindicator.h
+++ b/indra/llui/llloadingindicator.h
@@ -51,7 +51,7 @@ class LLLoadingIndicator
LOG_CLASS(LLLoadingIndicator);
public:
- struct Images : public LLInitParam::Block<Images>
+ struct Images : public LLInitParam::BatchBlock<Images>
{
Multiple<LLUIImage*> image;
@@ -63,7 +63,7 @@ public:
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
Optional<F32> images_per_sec;
- Batch<Images> images;
+ Optional<Images> images;
Params()
: images_per_sec("images_per_sec", 1.0f),
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 6cac841cde..badba7a416 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -947,7 +947,7 @@ LLMenuItemBranchGL::LLMenuItemBranchGL(const LLMenuItemBranchGL::Params& p)
LLMenuItemBranchGL::~LLMenuItemBranchGL()
{
- LLView::deleteViewByHandle(mBranchHandle);
+ delete mBranchHandle.get();
}
// virtual
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 0c4d4fc897..462d69be2e 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -201,7 +201,7 @@ public:
FormInput();
};
- struct FormElement : public LLInitParam::Choice<FormElement>
+ struct FormElement : public LLInitParam::ChoiceBlock<FormElement>
{
Alternative<FormButton> button;
Alternative<FormInput> input;
@@ -312,7 +312,7 @@ public:
Optional<LLNotificationContext*> context;
Optional<void*> responder;
- struct Functor : public LLInitParam::Choice<Functor>
+ struct Functor : public LLInitParam::ChoiceBlock<Functor>
{
Alternative<std::string> name;
Alternative<LLNotificationFunctorRegistry::ResponseFunctor> function;
diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h
index ab777d37a5..fb50c9c123 100644
--- a/indra/llui/llnotificationtemplate.h
+++ b/indra/llui/llnotificationtemplate.h
@@ -91,7 +91,7 @@ struct LLNotificationTemplate
// <notification> <unique/> </notification>
// as well as
// <notification> <unique> <context></context> </unique>...
- Flag dummy_val;
+ Optional<LLInitParam::Flag> dummy_val;
public:
Multiple<UniquenessContext> contexts;
@@ -147,7 +147,7 @@ struct LLNotificationTemplate
{}
};
- struct FormRef : public LLInitParam::Choice<FormRef>
+ struct FormRef : public LLInitParam::ChoiceBlock<FormRef>
{
Alternative<LLNotificationForm::Params> form;
Alternative<TemplateRef> form_template;
diff --git a/indra/llui/llnotificationvisibilityrule.h b/indra/llui/llnotificationvisibilityrule.h
index 78bdec2a8f..78788a275c 100644
--- a/indra/llui/llnotificationvisibilityrule.h
+++ b/indra/llui/llnotificationvisibilityrule.h
@@ -59,7 +59,7 @@ struct LLNotificationVisibilityRule
{}
};
- struct Rule : public LLInitParam::Choice<Rule>
+ struct Rule : public LLInitParam::ChoiceBlock<Rule>
{
Alternative<Filter> show;
Alternative<Filter> hide;
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index 790025cb2d..ab1c87caff 100644
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -96,9 +96,6 @@ public:
Params();
};
- // valid children for LLPanel are stored in this registry
- typedef LLDefaultChildRegistry child_registry_t;
-
protected:
friend class LLUICtrlFactory;
// RN: for some reason you can't just use LLUICtrlFactory::getDefaultParams as a default argument in VC8
diff --git a/indra/llui/llresizehandle.cpp b/indra/llui/llresizehandle.cpp
index c3a51c36c9..942e84eeb6 100644
--- a/indra/llui/llresizehandle.cpp
+++ b/indra/llui/llresizehandle.cpp
@@ -55,6 +55,8 @@ LLResizeHandle::LLResizeHandle(const LLResizeHandle::Params& p)
mImage( NULL ),
mMinWidth( p.min_width ),
mMinHeight( p.min_height ),
+ mMaxWidth(S32_MAX),
+ mMaxHeight(S32_MAX),
mCorner( p.corner )
{
if( RIGHT_BOTTOM == mCorner)
@@ -177,6 +179,11 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
new_width = mMinWidth;
delta_x = x_multiple * (mMinWidth - orig_rect.getWidth());
}
+ else if (new_width > mMaxWidth)
+ {
+ new_width = mMaxWidth;
+ delta_x = x_multiple * (mMaxWidth - orig_rect.getWidth());
+ }
S32 new_height = orig_rect.getHeight() + y_multiple * delta_y;
if( new_height < mMinHeight )
@@ -184,6 +191,11 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask)
new_height = mMinHeight;
delta_y = y_multiple * (mMinHeight - orig_rect.getHeight());
}
+ else if (new_height > mMaxHeight)
+ {
+ new_height = mMaxHeight;
+ delta_y = y_multiple * (mMaxHeight - orig_rect.getHeight());
+ }
switch( mCorner )
{
diff --git a/indra/llui/llresizehandle.h b/indra/llui/llresizehandle.h
index 531eb1db61..5cfe3fb63c 100644
--- a/indra/llui/llresizehandle.h
+++ b/indra/llui/llresizehandle.h
@@ -56,6 +56,9 @@ public:
void setResizeLimits( S32 min_width, S32 min_height ) { mMinWidth = min_width; mMinHeight = min_height; }
+ void setMaxWidth(S32 width) { mMaxWidth = width;}
+ void setMaxHeight(S32 height) { mMaxHeight = height;}
+
private:
BOOL pointInHandle( S32 x, S32 y );
@@ -66,7 +69,9 @@ private:
LLCoordGL mLastMouseDir;
LLPointer<LLUIImage> mImage;
S32 mMinWidth;
+ S32 mMaxWidth;
S32 mMinHeight;
+ S32 mMaxHeight;
const ECorner mCorner;
};
diff --git a/indra/llui/llscrolllistcolumn.h b/indra/llui/llscrolllistcolumn.h
index 12baea8e0c..b4d4a6d05e 100644
--- a/indra/llui/llscrolllistcolumn.h
+++ b/indra/llui/llscrolllistcolumn.h
@@ -95,7 +95,7 @@ public:
Optional<ESortDirection, SortNames> sort_direction;
Optional<bool> sort_ascending;
- struct Width : public LLInitParam::Choice<Width>
+ struct Width : public LLInitParam::ChoiceBlock<Width>
{
Alternative<bool> dynamic_width;
Alternative<S32> pixel_width;
@@ -112,7 +112,7 @@ public:
Optional<Width> width;
// either an image or label is used in column header
- struct Header : public LLInitParam::Choice<Header>
+ struct Header : public LLInitParam::ChoiceBlock<Header>
{
Alternative<std::string> label;
Alternative<LLUIImage*> image;
diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp
index 04919e6991..4b69360e33 100644
--- a/indra/llui/llsdparam.cpp
+++ b/indra/llui/llsdparam.cpp
@@ -45,7 +45,7 @@ LLParamSDParser::LLParamSDParser()
if (sReadFuncs.empty())
{
- registerParserFuncs<LLInitParam::NoParamValue>(readNoValue, &LLParamSDParser::writeNoValue);
+ registerParserFuncs<LLInitParam::Flag>(readFlag, &LLParamSDParser::writeFlag);
registerParserFuncs<S32>(readS32, &LLParamSDParser::writeTypedValue<S32>);
registerParserFuncs<U32>(readU32, &LLParamSDParser::writeU32Param);
registerParserFuncs<F32>(readF32, &LLParamSDParser::writeTypedValue<F32>);
@@ -72,7 +72,7 @@ bool LLParamSDParser::writeU32Param(LLParamSDParser::parser_t& parser, const voi
return true;
}
-bool LLParamSDParser::writeNoValue(LLParamSDParser::parser_t& parser, const void* val_ptr, const parser_t::name_stack_t& name_stack)
+bool LLParamSDParser::writeFlag(LLParamSDParser::parser_t& parser, const void* val_ptr, const parser_t::name_stack_t& name_stack)
{
LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser);
if (!sdparser.mWriteRootSD) return false;
@@ -226,7 +226,7 @@ LLSD* LLParamSDParser::getSDWriteNode(const parser_t::name_stack_t& name_stack)
return sd_to_write;
}
-bool LLParamSDParser::readNoValue(Parser& parser, void* val_ptr)
+bool LLParamSDParser::readFlag(Parser& parser, void* val_ptr)
{
LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
return self.mCurReadSD == &NO_VALUE_MARKER;
diff --git a/indra/llui/llsdparam.h b/indra/llui/llsdparam.h
index f776c781b3..a371c28f68 100644
--- a/indra/llui/llsdparam.h
+++ b/indra/llui/llsdparam.h
@@ -63,9 +63,9 @@ private:
LLSD* getSDWriteNode(const parser_t::name_stack_t& name_stack);
static bool writeU32Param(Parser& parser, const void* value_ptr, const parser_t::name_stack_t& name_stack);
- static bool writeNoValue(Parser& parser, const void* value_ptr, const parser_t::name_stack_t& name_stack);
+ static bool writeFlag(Parser& parser, const void* value_ptr, const parser_t::name_stack_t& name_stack);
- static bool readNoValue(Parser& parser, void* val_ptr);
+ static bool readFlag(Parser& parser, void* val_ptr);
static bool readS32(Parser& parser, void* val_ptr);
static bool readU32(Parser& parser, void* val_ptr);
static bool readF32(Parser& parser, void* val_ptr);
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 7d545a1ba6..384d9116fc 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -237,7 +237,7 @@ public:
friend class LLNormalTextSegment;
friend class LLUICtrlFactory;
- struct LineSpacingParams : public LLInitParam::Choice<LineSpacingParams>
+ struct LineSpacingParams : public LLInitParam::ChoiceBlock<LineSpacingParams>
{
Alternative<F32> multiple;
Alternative<S32> pixels;
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
new file mode 100644
index 0000000000..07beb147d7
--- /dev/null
+++ b/indra/llui/lltoolbar.cpp
@@ -0,0 +1,682 @@
+/**
+ * @file lltoolbar.cpp
+ * @author Richard Nelson
+ * @brief User customizable toolbar class
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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 <boost/foreach.hpp>
+#include "lltoolbar.h"
+
+#include "llcommandmanager.h"
+#include "llmenugl.h"
+#include "lltrans.h"
+
+// uncomment this and remove the one in llui.cpp when there is an external reference to this translation unit
+// thanks, MSVC!
+//static LLDefaultChildRegistry::Register<LLToolBar> r1("toolbar");
+
+namespace LLToolBarEnums
+{
+ LLLayoutStack::ELayoutOrientation getOrientation(SideType sideType)
+ {
+ LLLayoutStack::ELayoutOrientation orientation = LLLayoutStack::HORIZONTAL;
+
+ if ((sideType == SIDE_LEFT) || (sideType == SIDE_RIGHT))
+ {
+ orientation = LLLayoutStack::VERTICAL;
+ }
+
+ return orientation;
+ }
+}
+
+using namespace LLToolBarEnums;
+
+
+namespace LLInitParam
+{
+ void TypeValues<ButtonType>::declareValues()
+ {
+ declare("icons_with_text", BTNTYPE_ICONS_WITH_TEXT);
+ declare("icons_only", BTNTYPE_ICONS_ONLY);
+ }
+
+ void TypeValues<SideType>::declareValues()
+ {
+ declare("bottom", SIDE_BOTTOM);
+ declare("left", SIDE_LEFT);
+ declare("right", SIDE_RIGHT);
+ declare("top", SIDE_TOP);
+ }
+}
+
+LLToolBar::Params::Params()
+: button_display_mode("button_display_mode"),
+ commands("command"),
+ side("side", SIDE_TOP),
+ button_icon("button_icon"),
+ button_icon_and_text("button_icon_and_text"),
+ read_only("read_only", false),
+ wrap("wrap", true),
+ pad_left("pad_left"),
+ pad_top("pad_top"),
+ pad_right("pad_right"),
+ pad_bottom("pad_bottom"),
+ pad_between("pad_between"),
+ button_panel("button_panel")
+{}
+
+LLToolBar::LLToolBar(const LLToolBar::Params& p)
+: LLUICtrl(p),
+ mReadOnly(p.read_only),
+ mButtonType(p.button_display_mode),
+ mSideType(p.side),
+ mWrap(p.wrap),
+ mNeedsLayout(false),
+ mButtonPanel(NULL),
+ mCenteringStack(NULL),
+ mPadLeft(p.pad_left),
+ mPadRight(p.pad_right),
+ mPadTop(p.pad_top),
+ mPadBottom(p.pad_bottom),
+ mPadBetween(p.pad_between),
+ mPopupMenuHandle()
+{
+ mButtonParams[LLToolBarEnums::BTNTYPE_ICONS_WITH_TEXT] = p.button_icon_and_text;
+ mButtonParams[LLToolBarEnums::BTNTYPE_ICONS_ONLY] = p.button_icon;
+}
+
+LLToolBar::~LLToolBar()
+{
+ delete mPopupMenuHandle.get();
+}
+
+void LLToolBar::createContextMenu()
+{
+ if (!mPopupMenuHandle.get())
+ {
+ // Setup bindings specific to this instance for the context menu options
+
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commit_reg;
+ commit_reg.add("Toolbars.EnableSetting", boost::bind(&LLToolBar::onSettingEnable, this, _2));
+
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_reg;
+ enable_reg.add("Toolbars.CheckSetting", boost::bind(&LLToolBar::isSettingChecked, this, _2));
+
+ // Create the context menu
+ LLContextMenu* menu = LLUICtrlFactory::instance().createFromFile<LLContextMenu>("menu_toolbars.xml", LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
+
+ if (menu)
+ {
+ menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor"));
+
+ mPopupMenuHandle = menu->getHandle();
+ }
+ else
+ {
+ llwarns << "Unable to load toolbars context menu." << llendl;
+ }
+ }
+}
+
+void LLToolBar::initFromParams(const LLToolBar::Params& p)
+{
+ // Initialize the base object
+ LLUICtrl::initFromParams(p);
+
+ LLLayoutStack::ELayoutOrientation orientation = getOrientation(p.side);
+
+ LLLayoutStack::Params centering_stack_p;
+ centering_stack_p.name = "centering_stack";
+ centering_stack_p.rect = getLocalRect();
+ centering_stack_p.follows.flags = FOLLOWS_ALL;
+ centering_stack_p.orientation = orientation;
+ centering_stack_p.mouse_opaque = false;
+
+ mCenteringStack = LLUICtrlFactory::create<LLLayoutStack>(centering_stack_p);
+ addChild(mCenteringStack);
+
+ LLLayoutPanel::Params border_panel_p;
+ border_panel_p.name = "border_panel";
+ border_panel_p.rect = getLocalRect();
+ border_panel_p.auto_resize = true;
+ border_panel_p.user_resize = false;
+ border_panel_p.mouse_opaque = false;
+
+ mCenteringStack->addChild(LLUICtrlFactory::create<LLLayoutPanel>(border_panel_p));
+
+ LLLayoutPanel::Params center_panel_p;
+ center_panel_p.name = "center_panel";
+ center_panel_p.rect = getLocalRect();
+ center_panel_p.auto_resize = false;
+ center_panel_p.user_resize = false;
+ LLLayoutPanel* center_panel = LLUICtrlFactory::create<LLLayoutPanel>(center_panel_p);
+ mCenteringStack->addChild(center_panel);
+
+ LLPanel::Params button_panel_p(p.button_panel);
+ button_panel_p.rect = center_panel->getLocalRect();
+ button_panel_p.follows.flags = FOLLOWS_BOTTOM|FOLLOWS_LEFT;
+ mButtonPanel = LLUICtrlFactory::create<LLPanel>(button_panel_p);
+ center_panel->addChild(mButtonPanel);
+
+ mCenteringStack->addChild(LLUICtrlFactory::create<LLLayoutPanel>(border_panel_p));
+
+ BOOST_FOREACH(LLCommandId::Params params, p.commands)
+ {
+ addCommand(params);
+ }
+
+ mNeedsLayout = true;
+}
+
+bool LLToolBar::addCommand(const LLCommandId& commandId, int rank)
+{
+ LLCommand * command = LLCommandManager::instance().getCommand(commandId);
+ if (!command) return false;
+
+ // Create the button and do the things that don't need ordering
+ LLToolBarButton* button = createButton(commandId);
+ mButtonPanel->addChild(button);
+ mButtonMap.insert(std::make_pair(commandId, button));
+
+ // Insert the command and button in the right place in their respective lists
+ if ((rank >= mButtonCommands.size()) || (rank < 0))
+ {
+ // In that case, back load
+ mButtonCommands.push_back(commandId);
+ mButtons.push_back(button);
+ }
+ else
+ {
+ // Insert in place: iterate to the right spot...
+ std::list<LLToolBarButton*>::iterator it_button = mButtons.begin();
+ command_id_list_t::iterator it_command = mButtonCommands.begin();
+ while (rank > 0)
+ {
+ ++it_button;
+ ++it_command;
+ rank--;
+ }
+ // ...then insert
+ mButtonCommands.insert(it_command,commandId);
+ mButtons.insert(it_button,button);
+ }
+
+ mNeedsLayout = true;
+
+ return true;
+}
+
+bool LLToolBar::removeCommand(const LLCommandId& commandId)
+{
+ if (!hasCommand(commandId)) return false;
+
+ // First erase the map record
+ command_id_map::iterator it = mButtonMap.find(commandId);
+ mButtonMap.erase(it);
+
+ // Now iterate on the commands and buttons to identify the relevant records
+ std::list<LLToolBarButton*>::iterator it_button = mButtons.begin();
+ command_id_list_t::iterator it_command = mButtonCommands.begin();
+ while (*it_command != commandId)
+ {
+ ++it_button;
+ ++it_command;
+ }
+
+ // Delete the button and erase the command and button records
+ delete (*it_button);
+ mButtonCommands.erase(it_command);
+ mButtons.erase(it_button);
+
+ mNeedsLayout = true;
+
+ return true;
+}
+
+void LLToolBar::clearCommandsList()
+{
+ // Clears the commands list
+ mButtonCommands.clear();
+ // This will clear the buttons
+ createButtons();
+}
+
+bool LLToolBar::hasCommand(const LLCommandId& commandId) const
+{
+ if (commandId != LLCommandId::null)
+ {
+ command_id_map::const_iterator it = mButtonMap.find(commandId);
+ return (it != mButtonMap.end());
+ }
+
+ return false;
+}
+
+bool LLToolBar::enableCommand(const LLCommandId& commandId, bool enabled)
+{
+ LLButton * command_button = NULL;
+
+ if (commandId != LLCommandId::null)
+ {
+ command_id_map::iterator it = mButtonMap.find(commandId);
+ if (it != mButtonMap.end())
+ {
+ it->second->setEnabled(enabled);
+ }
+ }
+
+ return (command_button != NULL);
+}
+
+BOOL LLToolBar::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ LLRect button_panel_rect;
+ mButtonPanel->localRectToOtherView(mButtonPanel->getLocalRect(), &button_panel_rect, this);
+ BOOL handle_it_here = !mReadOnly && button_panel_rect.pointInRect(x, y);
+
+ if (handle_it_here)
+ {
+ createContextMenu();
+
+ LLContextMenu * menu = (LLContextMenu *) mPopupMenuHandle.get();
+
+ if (menu)
+ {
+ menu->show(x, y);
+
+ LLMenuGL::showPopup(this, menu, x, y);
+ }
+ }
+
+ return handle_it_here;
+}
+
+BOOL LLToolBar::isSettingChecked(const LLSD& userdata)
+{
+ BOOL retval = FALSE;
+
+ const std::string setting_name = userdata.asString();
+
+ if (setting_name == "icons_with_text")
+ {
+ retval = (mButtonType == BTNTYPE_ICONS_WITH_TEXT);
+ }
+ else if (setting_name == "icons_only")
+ {
+ retval = (mButtonType == BTNTYPE_ICONS_ONLY);
+ }
+
+ return retval;
+}
+
+void LLToolBar::onSettingEnable(const LLSD& userdata)
+{
+ llassert(!mReadOnly);
+
+ const std::string setting_name = userdata.asString();
+
+ if (setting_name == "icons_with_text")
+ {
+ setButtonType(BTNTYPE_ICONS_WITH_TEXT);
+ }
+ else if (setting_name == "icons_only")
+ {
+ setButtonType(BTNTYPE_ICONS_ONLY);
+ }
+}
+
+void LLToolBar::setButtonType(LLToolBarEnums::ButtonType button_type)
+{
+ bool regenerate_buttons = (mButtonType != button_type);
+
+ mButtonType = button_type;
+
+ if (regenerate_buttons)
+ {
+ createButtons();
+ }
+}
+
+void LLToolBar::resizeButtonsInRow(std::vector<LLToolBarButton*>& buttons_in_row, S32 max_row_girth)
+{
+ // make buttons in current row all same girth
+ BOOST_FOREACH(LLToolBarButton* button, buttons_in_row)
+ {
+ if (getOrientation(mSideType) == LLLayoutStack::HORIZONTAL)
+ {
+ button->reshape(button->mWidthRange.clamp(button->getRect().getWidth()), max_row_girth);
+ }
+ else // VERTICAL
+ {
+ button->reshape(max_row_girth, button->getRect().getHeight());
+ }
+ }
+}
+
+int LLToolBar::getRankFromPosition(S32 x, S32 y)
+{
+ int rank = 0;
+
+ LLLayoutStack::ELayoutOrientation orientation = getOrientation(mSideType);
+
+ // Simply compare the passed coord with the buttons outbound box
+ std::list<LLToolBarButton*>::iterator it_button = mButtons.begin();
+ std::list<LLToolBarButton*>::iterator end_button = mButtons.end();
+ while (it_button != end_button)
+ {
+ LLRect button_rect = (*it_button)->getRect();
+ if (((orientation == LLLayoutStack::HORIZONTAL) && (button_rect.mRight > x)) ||
+ ((orientation == LLLayoutStack::VERTICAL) && (button_rect.mTop > y)) )
+ {
+ llinfos << "Merov debug : rank compute: orientation = " << orientation << ", x = " << x << ", y = " << y << llendl;
+ llinfos << "Merov debug : rank compute: rect = " << button_rect.mLeft << ", " << button_rect.mTop << ", " << button_rect.mRight << ", " << button_rect.mBottom << llendl;
+ break;
+ }
+ rank++;
+ ++it_button;
+ }
+ llinfos << "Merov debug : rank = " << rank << llendl;
+
+ return rank;
+}
+
+void LLToolBar::updateLayoutAsNeeded()
+{
+ if (!mNeedsLayout) return;
+
+ LLLayoutStack::ELayoutOrientation orientation = getOrientation(mSideType);
+
+ // our terminology for orientation-agnostic layout is such that
+ // length refers to a distance in the direction we stack the buttons
+ // and girth refers to a distance in the direction buttons wrap
+ S32 max_row_girth = 0;
+ S32 max_row_length = 0;
+
+ S32 max_length;
+ S32 max_total_girth;
+ S32 cur_start;
+ S32 cur_row ;
+ S32 row_pad_start;
+ S32 row_pad_end;
+ S32 girth_pad_end;
+ S32 row_running_length;
+
+ if (orientation == LLLayoutStack::HORIZONTAL)
+ {
+ max_length = getRect().getWidth() - mPadLeft - mPadRight;
+ max_total_girth = getRect().getHeight() - mPadTop - mPadBottom;
+ row_pad_start = mPadLeft;
+ row_pad_end = mPadRight;
+ cur_row = mPadTop;
+ girth_pad_end = mPadBottom;
+ }
+ else // VERTICAL
+ {
+ max_length = getRect().getHeight() - mPadTop - mPadBottom;
+ max_total_girth = getRect().getWidth() - mPadLeft - mPadRight;
+ row_pad_start = mPadTop;
+ row_pad_end = mPadBottom;
+ cur_row = mPadLeft;
+ girth_pad_end = mPadRight;
+ }
+
+ row_running_length = row_pad_start;
+ cur_start = row_pad_start;
+
+
+ LLRect panel_rect = mButtonPanel->getLocalRect();
+
+ std::vector<LLToolBarButton*> buttons_in_row;
+
+ BOOST_FOREACH(LLToolBarButton* button, mButtons)
+ {
+ button->reshape(button->mWidthRange.getMin(), button->mDesiredHeight);
+ button->autoResize();
+
+ S32 button_clamped_width = button->mWidthRange.clamp(button->getRect().getWidth());
+ S32 button_length = (orientation == LLLayoutStack::HORIZONTAL)
+ ? button_clamped_width
+ : button->getRect().getHeight();
+ S32 button_girth = (orientation == LLLayoutStack::HORIZONTAL)
+ ? button->getRect().getHeight()
+ : button_clamped_width;
+
+ // wrap if needed
+ if (mWrap
+ && row_running_length + button_length > max_length // out of room...
+ && cur_start != row_pad_start) // ...and not first button in row
+ {
+ if (orientation == LLLayoutStack::VERTICAL)
+ { // row girth (width in this case) is clamped to allowable button widths
+ max_row_girth = button->mWidthRange.clamp(max_row_girth);
+ }
+
+ // make buttons in current row all same girth
+ resizeButtonsInRow(buttons_in_row, max_row_girth);
+ buttons_in_row.clear();
+
+ max_row_length = llmax(max_row_length, row_running_length);
+ row_running_length = row_pad_start;
+ cur_start = row_pad_start;
+ cur_row += max_row_girth + mPadBetween;
+ max_row_girth = 0;
+ }
+
+ LLRect button_rect;
+ if (orientation == LLLayoutStack::HORIZONTAL)
+ {
+ button_rect.setLeftTopAndSize(cur_start, panel_rect.mTop - cur_row, button_clamped_width, button->getRect().getHeight());
+ }
+ else // VERTICAL
+ {
+ button_rect.setLeftTopAndSize(cur_row, panel_rect.mTop - cur_start, button_clamped_width, button->getRect().getHeight());
+ }
+ button->setShape(button_rect);
+
+ buttons_in_row.push_back(button);
+
+ row_running_length += button_length + mPadBetween;
+ cur_start = row_running_length;
+ max_row_girth = llmax(button_girth, max_row_girth);
+ }
+
+ // final resizing in "girth" direction
+ S32 total_girth = cur_row // current row position...
+ + max_row_girth // ...incremented by size of final row...
+ + girth_pad_end; // ...plus padding reserved on end
+ max_row_length = llmax(max_row_length, row_running_length - mPadBetween + row_pad_end);
+
+ resizeButtonsInRow(buttons_in_row, max_row_girth);
+
+ // grow and optionally shift toolbar to accommodate buttons
+ if (orientation == LLLayoutStack::HORIZONTAL)
+ {
+ if (mSideType == SIDE_TOP)
+ { // shift down to maintain top edge
+ translate(0, getRect().getHeight() - total_girth);
+ }
+
+ reshape(getRect().getWidth(), total_girth);
+ mButtonPanel->reshape(max_row_length, total_girth);
+ }
+ else // VERTICAL
+ {
+ if (mSideType == SIDE_RIGHT)
+ { // shift left to maintain right edge
+ translate(getRect().getWidth() - total_girth, 0);
+ }
+
+ reshape(total_girth, getRect().getHeight());
+ mButtonPanel->reshape(total_girth, max_row_length);
+ }
+
+ // make parent fit button panel
+ mButtonPanel->getParent()->setShape(mButtonPanel->getLocalRect());
+
+ // re-center toolbar buttons
+ mCenteringStack->updateLayout();
+
+ // don't clear flag until after we've resized ourselves, to avoid laying out every frame
+ mNeedsLayout = false;
+}
+
+
+void LLToolBar::draw()
+{
+ if (mButtons.empty()) return;
+ updateLayoutAsNeeded();
+ // rect may have shifted during layout
+ LLUI::popMatrix();
+ LLUI::pushMatrix();
+ LLUI::translate((F32)getRect().mLeft, (F32)getRect().mBottom, 0.f);
+
+ LLUICtrl::draw();
+}
+
+void LLToolBar::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ LLUICtrl::reshape(width, height, called_from_parent);
+ mNeedsLayout = true;
+}
+
+void LLToolBar::createButtons()
+{
+ BOOST_FOREACH(LLToolBarButton* button, mButtons)
+ {
+ delete button;
+ }
+ mButtons.clear();
+ mButtonMap.clear();
+
+ BOOST_FOREACH(LLCommandId& command_id, mButtonCommands)
+ {
+ LLToolBarButton* button = createButton(command_id);
+ mButtons.push_back(button);
+ mButtonPanel->addChild(button);
+ mButtonMap.insert(std::make_pair(command_id, button));
+ }
+ mNeedsLayout = true;
+}
+
+LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)
+{
+ LLCommand* commandp = LLCommandManager::instance().getCommand(id);
+ if (!commandp) return NULL;
+
+ std::string label = LLTrans::getString(commandp->labelRef());
+ std::string tooltip = label + "\n" + LLTrans::getString(commandp->tooltipRef());
+
+ LLToolBarButton::Params button_p;
+ button_p.name = id.name();
+ button_p.label = label;
+ button_p.tool_tip = tooltip;
+ button_p.image_overlay = LLUI::getUIImage(commandp->icon());
+ button_p.overwriteFrom(mButtonParams[mButtonType]);
+ LLToolBarButton* button = LLUICtrlFactory::create<LLToolBarButton>(button_p);
+
+ if (!mReadOnly)
+ {
+ LLUICtrl::CommitCallbackParam cbParam;
+ cbParam.function_name = commandp->executeFunctionName();
+ cbParam.parameter = commandp->executeParameters();
+ button->setCommitCallback(cbParam);
+ button->setStartDragCallback(mStartDragItemCallback);
+ button->setHandleDragCallback(mHandleDragItemCallback);
+ }
+
+ button->setCommandId(id);
+ return button;
+
+}
+
+BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ llinfos << "Merov debug : handleDragAndDrop. drop = " << drop << ", x = " << x << ", y = " << y << llendl;
+ // If we have a drop callback, that means that we can handle the drop
+ BOOL handled = (mHandleDropCallback ? TRUE : FALSE);
+
+ // if drop is set, it's time to call the callback to get the operation done
+ if (handled && drop)
+ {
+ handled = mHandleDropCallback(cargo_data, x, y ,this);
+ }
+
+ // We accept only single tool drop on toolbars
+ *accept = (handled ? ACCEPT_YES_SINGLE : ACCEPT_NO);
+
+ // We'll use that flag to change the visual aspect of the toolbar target on draw()
+ mDragAndDropTarget = handled;
+
+ return handled;
+}
+
+LLToolBarButton::LLToolBarButton(const Params& p)
+: LLButton(p),
+ mMouseDownX(0),
+ mMouseDownY(0),
+ mWidthRange(p.button_width),
+ mDesiredHeight(p.desired_height),
+ mId("")
+{
+}
+
+BOOL LLToolBarButton::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ mMouseDownX = x;
+ mMouseDownY = y;
+ return LLButton::handleMouseDown(x, y, mask);
+}
+
+BOOL LLToolBarButton::handleHover(S32 x, S32 y, MASK mask)
+{
+// llinfos << "Merov debug: handleHover, x = " << x << ", y = " << y << ", mouse = " << hasMouseCapture() << llendl;
+ BOOL handled = FALSE;
+
+ if (hasMouseCapture() && mStartDragItemCallback && mHandleDragItemCallback)
+ {
+ if (!mIsDragged)
+ {
+ mStartDragItemCallback(x,y,mId.uuid());
+ mIsDragged = true;
+ handled = TRUE;
+ }
+ else
+ {
+ handled = mHandleDragItemCallback(x,y,mId.uuid(),LLAssetType::AT_WIDGET);
+ }
+ }
+ else
+ {
+ handled = LLButton::handleHover(x, y, mask);
+ }
+ return handled;
+}
+
diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h
new file mode 100644
index 0000000000..a35f6d9db1
--- /dev/null
+++ b/indra/llui/lltoolbar.h
@@ -0,0 +1,218 @@
+/**
+ * @file lltoolbar.h
+ * @author Richard Nelson
+ * @brief User customizable toolbar class
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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$
+ */
+
+#ifndef LL_LLTOOLBAR_H
+#define LL_LLTOOLBAR_H
+
+#include "llbutton.h"
+#include "llcommandmanager.h"
+#include "lllayoutstack.h"
+#include "lluictrl.h"
+#include "llcommandmanager.h"
+#include "llassettype.h"
+
+class LLToolBar;
+
+typedef boost::function<void (S32 x, S32 y, const LLUUID& uuid)> tool_startdrag_callback_t;
+typedef boost::function<BOOL (S32 x, S32 y, const LLUUID& uuid, LLAssetType::EType type)> tool_handledrag_callback_t;
+typedef boost::function<BOOL (void* data, S32 x, S32 y, LLToolBar* toolbar)> tool_handledrop_callback_t;
+
+class LLToolBarButton : public LLButton
+{
+ friend class LLToolBar;
+public:
+ struct Params : public LLInitParam::Block<Params, LLButton::Params>
+ {
+ Optional<LLUI::RangeS32> button_width;
+ Optional<S32> desired_height;
+
+ Params()
+ : button_width("button_width"),
+ desired_height("desired_height", 20)
+ {}
+
+ };
+
+ LLToolBarButton(const Params& p);
+
+ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ BOOL handleHover(S32 x, S32 y, MASK mask);
+ void setCommandId(const LLCommandId& id) { mId = id; }
+
+ void setStartDragCallback(tool_startdrag_callback_t cb) { mStartDragItemCallback = cb; }
+ void setHandleDragCallback(tool_handledrag_callback_t cb) { mHandleDragItemCallback = cb; }
+private:
+ LLCommandId mId;
+ S32 mMouseDownX;
+ S32 mMouseDownY;
+ LLUI::RangeS32 mWidthRange;
+ S32 mDesiredHeight;
+ bool mIsDragged;
+ tool_startdrag_callback_t mStartDragItemCallback;
+ tool_handledrag_callback_t mHandleDragItemCallback;
+};
+
+
+namespace LLToolBarEnums
+{
+ enum ButtonType
+ {
+ BTNTYPE_ICONS_WITH_TEXT = 0,
+ BTNTYPE_ICONS_ONLY,
+
+ BTNTYPE_COUNT
+ };
+
+ enum SideType
+ {
+ SIDE_BOTTOM,
+ SIDE_LEFT,
+ SIDE_RIGHT,
+ SIDE_TOP,
+ };
+}
+
+// NOTE: This needs to occur before Param block declaration for proper compilation.
+namespace LLInitParam
+{
+ template<>
+ struct TypeValues<LLToolBarEnums::ButtonType> : public TypeValuesHelper<LLToolBarEnums::ButtonType>
+ {
+ static void declareValues();
+ };
+
+ template<>
+ struct TypeValues<LLToolBarEnums::SideType> : public TypeValuesHelper<LLToolBarEnums::SideType>
+ {
+ static void declareValues();
+ };
+}
+
+
+class LLToolBar
+: public LLUICtrl
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+ {
+ Mandatory<LLToolBarEnums::ButtonType> button_display_mode;
+ Mandatory<LLToolBarEnums::SideType> side;
+
+ Optional<LLToolBarButton::Params> button_icon,
+ button_icon_and_text;
+
+ Optional<bool> read_only,
+ wrap;
+
+ Optional<S32> pad_left,
+ pad_top,
+ pad_right,
+ pad_bottom,
+ pad_between;
+ // get rid of this
+ Multiple<LLCommandId::Params> commands;
+
+ Optional<LLPanel::Params> button_panel;
+
+ Params();
+ };
+
+ // virtuals
+ void draw();
+ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+ int getRankFromPosition(S32 x, S32 y);
+ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+ virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+
+ bool addCommand(const LLCommandId& commandId, int rank = -1);
+ bool removeCommand(const LLCommandId& commandId);
+ bool hasCommand(const LLCommandId& commandId) const;
+ bool enableCommand(const LLCommandId& commandId, bool enabled);
+ void setStartDragCallback(tool_startdrag_callback_t cb) { mStartDragItemCallback = cb; }
+ void setHandleDragCallback(tool_handledrag_callback_t cb) { mHandleDragItemCallback = cb; }
+ void setHandleDropCallback(tool_handledrop_callback_t cb) { mHandleDropCallback = cb; }
+
+ LLToolBarButton* createButton(const LLCommandId& id);
+
+protected:
+ friend class LLUICtrlFactory;
+ LLToolBar(const Params&);
+ ~LLToolBar();
+
+ void initFromParams(const Params&);
+ tool_startdrag_callback_t mStartDragItemCallback;
+ tool_handledrag_callback_t mHandleDragItemCallback;
+ tool_handledrop_callback_t mHandleDropCallback;
+ bool mDragAndDropTarget;
+
+public:
+ // Methods used in loading and saving toolbar settings
+ void setButtonType(LLToolBarEnums::ButtonType button_type);
+ LLToolBarEnums::ButtonType getButtonType() { return mButtonType; }
+ command_id_list_t& getCommandsList() { return mButtonCommands; }
+ void clearCommandsList();
+
+private:
+ void createContextMenu();
+ void updateLayoutAsNeeded();
+ void createButtons();
+ void resizeButtonsInRow(std::vector<LLToolBarButton*>& buttons_in_row, S32 max_row_girth);
+ BOOL isSettingChecked(const LLSD& userdata);
+ void onSettingEnable(const LLSD& userdata);
+
+ const bool mReadOnly;
+
+ std::list<LLToolBarButton*> mButtons;
+ command_id_list_t mButtonCommands;
+ typedef std::map<LLCommandId, LLToolBarButton*> command_id_map;
+ command_id_map mButtonMap;
+
+ LLToolBarEnums::ButtonType mButtonType;
+ LLLayoutStack* mCenteringStack;
+ LLLayoutStack* mWrapStack;
+ LLPanel* mButtonPanel;
+ LLToolBarEnums::SideType mSideType;
+
+ bool mWrap;
+ bool mNeedsLayout;
+ S32 mPadLeft,
+ mPadRight,
+ mPadTop,
+ mPadBottom,
+ mPadBetween;
+
+ LLToolBarButton::Params mButtonParams[LLToolBarEnums::BTNTYPE_COUNT];
+
+ LLHandle<class LLContextMenu> mPopupMenuHandle;
+};
+
+
+#endif // LL_LLTOOLBAR_H
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 58ba9e05f5..76a12e649b 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -41,6 +41,7 @@
#include "llgl.h"
// Project includes
+#include "llcommandmanager.h"
#include "llcontrol.h"
#include "llui.h"
#include "lluicolortable.h"
@@ -57,6 +58,7 @@
#include "llfiltereditor.h"
#include "llflyoutbutton.h"
#include "llsearcheditor.h"
+#include "lltoolbar.h"
// for XUIParse
#include "llquaternion.h"
@@ -94,6 +96,7 @@ static LLDefaultChildRegistry::Register<LLSearchEditor> register_search_editor("
// register other widgets which otherwise may not be linked in
static LLDefaultChildRegistry::Register<LLLoadingIndicator> register_loading_indicator("loading_indicator");
+static LLDefaultChildRegistry::Register<LLToolBar> register_toolbar("toolbar");
//
// Functions
@@ -1615,6 +1618,7 @@ void LLUI::initClass(const settings_map_t& settings,
// Callbacks for associating controls with floater visibilty:
reg.add("Floater.Toggle", boost::bind(&LLFloaterReg::toggleFloaterInstance, _2));
+ reg.add("Floater.ToolbarToggle", boost::bind(&LLFloaterReg::toggleToolbarFloaterInstance, _2));
reg.add("Floater.Show", boost::bind(&LLFloaterReg::showFloaterInstance, _2));
reg.add("Floater.Hide", boost::bind(&LLFloaterReg::hideFloaterInstance, _2));
reg.add("Floater.InitToVisibilityControl", boost::bind(&LLFloaterReg::initUICtrlToFloaterVisibilityControl, _1, _2));
@@ -1633,6 +1637,9 @@ void LLUI::initClass(const settings_map_t& settings,
// Used by menus along with Floater.Toggle to display visibility as a checkmark
LLUICtrl::EnableCallbackRegistry::defaultRegistrar().add("Floater.Visible", boost::bind(&LLFloaterReg::floaterInstanceVisible, _2));
+
+ // Parse the master list of commands
+ LLCommandManager::load();
}
void LLUI::cleanupClass()
@@ -2100,7 +2107,7 @@ namespace LLInitParam
void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()
{
- if (control.isProvided())
+ if (control.isProvided() && !control().empty())
{
updateValue(LLUIColorTable::instance().getColor(control));
}
@@ -2257,9 +2264,11 @@ namespace LLInitParam
// in this case, that is left+width and bottom+height
LLRect& value = getValue();
+ right.set(value.mRight, false);
left.set(value.mLeft, make_block_authoritative);
width.set(value.getWidth(), make_block_authoritative);
+ top.set(value.mTop, false);
bottom.set(value.mBottom, make_block_authoritative);
height.set(value.getHeight(), make_block_authoritative);
}
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 7801a01ace..28e84fa444 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -41,6 +41,7 @@
#include <boost/signals2.hpp>
#include "lllazyvalue.h"
#include "llframetimer.h"
+#include <limits>
// LLUIFactory
#include "llsd.h"
@@ -148,6 +149,122 @@ class LLUI
LOG_CLASS(LLUI);
public:
//
+ // Classes
+ //
+
+ struct RangeS32
+ {
+ struct Params : public LLInitParam::Block<Params>
+ {
+ Optional<S32> minimum,
+ maximum;
+
+ Params()
+ : minimum("min", 0),
+ maximum("max", S32_MAX)
+ {}
+ };
+
+ // correct for inverted params
+ RangeS32(const Params& p = Params())
+ : mMin(p.minimum),
+ mMax(p.maximum)
+ {
+ sanitizeRange();
+ }
+
+ RangeS32(S32 minimum, S32 maximum)
+ : mMin(minimum),
+ mMax(maximum)
+ {
+ sanitizeRange();
+ }
+
+ S32 clamp(S32 input)
+ {
+ if (input < mMin) return mMin;
+ if (input > mMax) return mMax;
+ return input;
+ }
+
+ void setRange(S32 minimum, S32 maximum)
+ {
+ mMin = minimum;
+ mMax = maximum;
+ sanitizeRange();
+ }
+
+ S32 getMin() { return mMin; }
+ S32 getMax() { return mMax; }
+
+ bool operator==(const RangeS32& other) const
+ {
+ return mMin == other.mMin
+ && mMax == other.mMax;
+ }
+ private:
+ void sanitizeRange()
+ {
+ if (mMin > mMax)
+ {
+ llwarns << "Bad interval range (" << mMin << ", " << mMax << ")" << llendl;
+ // since max is usually the most dangerous one to ignore (buffer overflow, etc), prefer it
+ // in the case of a malformed range
+ mMin = mMax;
+ }
+ }
+
+
+ S32 mMin,
+ mMax;
+ };
+
+ struct ClampedS32 : public RangeS32
+ {
+ struct Params : public LLInitParam::Block<Params, RangeS32::Params>
+ {
+ Mandatory<S32> value;
+
+ Params()
+ : value("", 0)
+ {
+ addSynonym(value, "value");
+ }
+ };
+
+ ClampedS32(const Params& p)
+ : RangeS32(p)
+ {}
+
+ ClampedS32(const RangeS32& range)
+ : RangeS32(range)
+ {
+ // set value here, after range has been sanitized
+ mValue = clamp(0);
+ }
+
+ ClampedS32(S32 value, const RangeS32& range = RangeS32())
+ : RangeS32(range)
+ {
+ mValue = clamp(value);
+ }
+
+ S32 get()
+ {
+ return mValue;
+ }
+
+ void set(S32 value)
+ {
+ mValue = clamp(value);
+ }
+
+
+ private:
+ S32 mValue;
+ };
+
+ //
// Methods
//
typedef std::map<std::string, LLControlGroup*> settings_map_t;
@@ -365,7 +482,7 @@ template <typename T> LLRegisterWith<LLInitClassList> LLInitClass<T>::sRegister(
template <typename T> LLRegisterWith<LLDestroyClassList> LLDestroyClass<T>::sRegister(&T::destroyClass);
// useful parameter blocks
-struct TimeIntervalParam : public LLInitParam::Choice<TimeIntervalParam>
+struct TimeIntervalParam : public LLInitParam::ChoiceBlock<TimeIntervalParam>
{
Alternative<F32> seconds;
Alternative<S32> frames;
diff --git a/indra/llui/lluicolortable.h b/indra/llui/lluicolortable.h
index 76518789ec..6a7a681d57 100644
--- a/indra/llui/lluicolortable.h
+++ b/indra/llui/lluicolortable.h
@@ -44,7 +44,7 @@ LOG_CLASS(LLUIColorTable);
typedef std::map<std::string, LLUIColor> string_color_map_t;
public:
- struct ColorParams : LLInitParam::Choice<ColorParams>
+ struct ColorParams : LLInitParam::ChoiceBlock<ColorParams>
{
Alternative<LLColor4> value;
Alternative<std::string> reference;
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index d58df5801b..5e8bf498c0 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -992,6 +992,16 @@ void LLUICtrl::setTransparencyType(ETypeTransparency type)
mTransparencyType = type;
}
+boost::signals2::connection LLUICtrl::setCommitCallback(const CommitCallbackParam& cb)
+{
+ return setCommitCallback(initCommitCallback(cb));
+}
+
+boost::signals2::connection LLUICtrl::setValidateCallback(const EnableCallbackParam& cb)
+{
+ return setValidateCallback(initEnableCallback(cb));
+}
+
boost::signals2::connection LLUICtrl::setCommitCallback( const commit_signal_t::slot_type& cb )
{
if (!mCommitSignal) mCommitSignal = new commit_signal_t();
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index 09bed9b958..a8a4e3191d 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -76,14 +76,14 @@ public:
Optional<enable_callback_t> function;
};
- struct EnableControls : public LLInitParam::Choice<EnableControls>
+ struct EnableControls : public LLInitParam::ChoiceBlock<EnableControls>
{
Alternative<std::string> enabled;
Alternative<std::string> disabled;
EnableControls();
};
- struct ControlVisibility : public LLInitParam::Choice<ControlVisibility>
+ struct ControlVisibility : public LLInitParam::ChoiceBlock<ControlVisibility>
{
Alternative<std::string> visible;
Alternative<std::string> invisible;
@@ -235,6 +235,9 @@ public:
// topic then put in help_topic_out
bool findHelpTopic(std::string& help_topic_out);
+ boost::signals2::connection setCommitCallback(const CommitCallbackParam& cb);
+ boost::signals2::connection setValidateCallback(const EnableCallbackParam& cb);
+
boost::signals2::connection setCommitCallback( const commit_signal_t::slot_type& cb );
boost::signals2::connection setValidateCallback( const enable_signal_t::slot_type& cb );
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index d345ad4cd0..d612ad5005 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -125,12 +125,12 @@ private:
// base case for recursion, there are NO base classes of LLInitParam::BaseBlock
template<int DUMMY>
- class ParamDefaults<LLInitParam::BaseBlockWithFlags, DUMMY> : public LLSingleton<ParamDefaults<LLInitParam::BaseBlockWithFlags, DUMMY> >
+ class ParamDefaults<LLInitParam::BaseBlock, DUMMY> : public LLSingleton<ParamDefaults<LLInitParam::BaseBlock, DUMMY> >
{
public:
- const LLInitParam::BaseBlockWithFlags& get() { return mBaseBlock; }
+ const LLInitParam::BaseBlock& get() { return mBaseBlock; }
private:
- LLInitParam::BaseBlockWithFlags mBaseBlock;
+ LLInitParam::BaseBlock mBaseBlock;
};
public:
@@ -172,7 +172,7 @@ public:
static T* createFromFile(const std::string &filename, LLView *parent, const widget_registry_t& registry, LLXMLNodePtr output_node = NULL)
{
T* widget = NULL;
-
+
std::string skinned_filename = findSkinnedFilename(filename);
instance().pushFileName(filename);
{
@@ -201,10 +201,10 @@ public:
// not of right type, so delete it
if (!widget)
{
+ llwarns << "Widget in " << filename << " was of type " << typeid(view).name() << " instead of expected type " << typeid(T).name() << llendl;
delete view;
view = NULL;
}
-
}
}
fail:
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 60452b9ae4..e10c2f0d1e 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -1826,13 +1826,6 @@ LLView* LLView::findNextSibling(LLView* child)
return (next_it != mChildList.end()) ? *next_it : NULL;
}
-void LLView::deleteViewByHandle(LLHandle<LLView> handle)
-{
- LLView* viewp = handle.get();
-
- delete viewp;
-}
-
LLCoordGL getNeededTranslation(const LLRect& input, const LLRect& constraint, BOOL allow_partial_outside)
{
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 594a5eec6b..a1c46f3bf3 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -95,13 +95,10 @@ private:
static std::vector<LLViewDrawContext*> sDrawContextStack;
};
-class LLViewWidgetRegistry : public LLChildRegistry<LLViewWidgetRegistry>
-{};
-
class LLView : public LLMouseHandler, public LLMortician, public LLFocusableElement
{
public:
- struct Follows : public LLInitParam::Choice<Follows>
+ struct Follows : public LLInitParam::ChoiceBlock<Follows>
{
Alternative<std::string> string;
Alternative<U32> flags;
@@ -150,7 +147,8 @@ public:
Params();
};
- typedef LLViewWidgetRegistry child_registry_t;
+ // most widgets are valid children of LLView
+ typedef LLDefaultChildRegistry child_registry_t;
void initFromParams(const LLView::Params&);
@@ -467,6 +465,20 @@ public:
return dynamic_cast<T*>(widgetp);
}
+ template <class T> T* getParentByType() const
+ {
+ LLView* parent = getParent();
+ while(parent)
+ {
+ if (dynamic_cast<T*>(parent))
+ {
+ return static_cast<T*>(parent);
+ }
+ parent = parent->getParent();
+ }
+ return NULL;
+ }
+
//////////////////////////////////////////////
// statics
//////////////////////////////////////////////
@@ -482,7 +494,6 @@ public:
// return query for iterating over focus roots in tab order
static const LLCtrlQuery & getFocusRootsQuery();
- static void deleteViewByHandle(LLHandle<LLView> handle);
static LLWindow* getWindow(void) { return LLUI::sWindow; }
// Set up params after XML load before calling new(),