diff options
Diffstat (limited to 'indra/llui')
-rw-r--r-- | indra/llui/CMakeLists.txt | 6 | ||||
-rw-r--r-- | indra/llui/llbutton.cpp | 26 | ||||
-rw-r--r-- | indra/llui/llbutton.h | 21 | ||||
-rw-r--r-- | indra/llui/llcommandmanager.cpp | 154 | ||||
-rw-r--r-- | indra/llui/llcommandmanager.h | 157 | ||||
-rw-r--r-- | indra/llui/lldockcontrol.cpp | 3 | ||||
-rw-r--r-- | indra/llui/llfloaterreg.cpp | 11 | ||||
-rw-r--r-- | indra/llui/llfloaterreg.h | 1 | ||||
-rw-r--r-- | indra/llui/lllayoutstack.cpp | 14 | ||||
-rw-r--r-- | indra/llui/lllayoutstack.h | 26 | ||||
-rw-r--r-- | indra/llui/llmenugl.cpp | 2 | ||||
-rw-r--r-- | indra/llui/llnotifications.cpp | 1 | ||||
-rw-r--r-- | indra/llui/llnotificationtemplate.h | 4 | ||||
-rw-r--r-- | indra/llui/llscrollcontainer.cpp | 9 | ||||
-rw-r--r-- | indra/llui/llscrollcontainer.h | 1 | ||||
-rw-r--r-- | indra/llui/llsdparam.cpp | 2 | ||||
-rw-r--r-- | indra/llui/lltoolbar.cpp | 505 | ||||
-rw-r--r-- | indra/llui/lltoolbar.h | 169 | ||||
-rw-r--r-- | indra/llui/lltoolbarview.cpp | 223 | ||||
-rw-r--r-- | indra/llui/lltoolbarview.h | 90 | ||||
-rw-r--r-- | indra/llui/llui.cpp | 7 | ||||
-rw-r--r-- | indra/llui/lluictrlfactory.h | 10 | ||||
-rw-r--r-- | indra/llui/llview.cpp | 7 | ||||
-rw-r--r-- | indra/llui/llview.h | 1 |
24 files changed, 1403 insertions, 47 deletions
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index b3b2f4ae56..4212812558 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -35,6 +35,7 @@ set(llui_SOURCE_FILES llcheckboxctrl.cpp llclipboard.cpp llcombobox.cpp + llcommandmanager.cpp llconsole.cpp llcontainerview.cpp llctrlselectioninterface.cpp @@ -99,6 +100,8 @@ set(llui_SOURCE_FILES lltimectrl.cpp lltransutil.cpp lltoggleablemenu.cpp + lltoolbar.cpp + lltoolbarview.cpp lltooltip.cpp llui.cpp lluicolortable.cpp @@ -131,6 +134,7 @@ set(llui_HEADER_FILES llcheckboxctrl.h llclipboard.h llcombobox.h + llcommandmanager.h llconsole.h llcontainerview.h llctrlselectioninterface.h @@ -200,6 +204,8 @@ set(llui_HEADER_FILES lltextvalidate.h lltimectrl.h lltoggleablemenu.h + lltoolbar.h + lltoolbarview.h lltooltip.h lltransutil.h lluicolortable.h diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 2459429f6e..06781f1bdf 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)); @@ -919,7 +919,7 @@ void LLButton::setToggleState(BOOL b) void LLButton::setFlashing( BOOL b ) { - if (b != mFlashing) + if ((bool)b != mFlashing) { mFlashing = b; mFlashingTimer.reset(); @@ -989,11 +989,27 @@ 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) { - setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mLeft + label_width + mLeftHPad + mRightHPad , getRect().mBottom)); + switch(mImageOverlayAlignment) + { + case LLFontGL::LEFT: + case LLFontGL::RIGHT: + min_width += mImageOverlay->getWidth() + mImgOverlayLabelSpace; + break; + case LLFontGL::HCENTER: + break; + default: + // draw nothing + break; + } + } + if (btn_width < min_width) + { + reshape(min_width, getRect().getHeight()); } } } diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 5968916006..bc5e69fad5 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -327,15 +327,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 +354,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/llcommandmanager.cpp b/indra/llui/llcommandmanager.cpp new file mode 100644 index 0000000000..783990780b --- /dev/null +++ b/indra/llui/llcommandmanager.cpp @@ -0,0 +1,154 @@ +/** + * @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() + : function("function") + , available_in_toybox("available_in_toybox", false) + , icon("icon") + , label_ref("label_ref") + , name("name") + , param("param") + , tooltip_ref("tooltip_ref") +{ +} + +LLCommand::LLCommand(const LLCommand::Params& p) + : mFunction(p.function) + , mAvailableInToybox(p.available_in_toybox) + , mIcon(p.icon) + , mIdentifier(p.name) + , mLabelRef(p.label_ref) + , mParam(p.param) + , mTooltipRef(p.tooltip_ref) +{ +} + + +// +// 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; +} + +void LLCommandManager::addCommand(LLCommand * command) +{ + mCommandIndices[command->id()] = 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..8435d915f3 --- /dev/null +++ b/indra/llui/llcommandmanager.h @@ -0,0 +1,157 @@ +/** + * @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) + {} + + LLCommandId(const Params& p) + : mName(p.name) + {} + + const std::string& name() const { return mName; } + + 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; +}; + +class LLCommand +{ +public: + struct Params : public LLInitParam::Block<Params> + { + Mandatory<bool> available_in_toybox; + Mandatory<std::string> function; + Mandatory<std::string> icon; + Mandatory<std::string> label_ref; + Mandatory<std::string> name; + Optional<std::string> param; + Mandatory<std::string> tooltip_ref; + + Params(); + }; + + LLCommand(const LLCommand::Params& p); + + const bool availableInToybox() const { return mAvailableInToybox; } + const std::string& functionName() const { return mFunction; } + const std::string& icon() const { return mIcon; } + const LLCommandId& id() const { return mIdentifier; } + const std::string& labelRef() const { return mLabelRef; } + const std::string& param() const { return mParam; } + const std::string& tooltipRef() const { return mTooltipRef; } + +private: + LLCommandId mIdentifier; + + bool mAvailableInToybox; + std::string mFunction; + std::string mIcon; + std::string mLabelRef; + std::string mParam; + std::string mTooltipRef; +}; + + +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); + + static bool load(); + +protected: + void addCommand(LLCommand * command); + +private: + typedef std::map<LLCommandId, U32> CommandIndexMap; + typedef std::vector<LLCommand *> CommandVector; + + CommandVector mCommands; + CommandIndexMap mCommandIndices; +}; + + +#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/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp index fc7dcfcc4e..bc740dde17 100644 --- a/indra/llui/llfloaterreg.cpp +++ b/indra/llui/llfloaterreg.cpp @@ -453,6 +453,17 @@ void LLFloaterReg::toggleFloaterInstance(const LLSD& sdname) } //static +void LLFloaterReg::toggleToolbarFloaterInstance(const LLSD& sdname) +{ + // Do some extra logic here for 3-state toolbar floater toggling madness :) + + LLSD key; + std::string name = sdname.asString(); + parse_name_key(name, key); + toggleInstance(name, key); +} + +//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..0d1f608e61 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -55,6 +55,7 @@ LLLayoutPanel::LLLayoutPanel(const Params& p) mMaxDim(p.max_dim), mAutoResize(p.auto_resize), mUserResize(p.user_resize), + mFitContent(p.fit_content), mCollapsed(FALSE), mCollapseAmt(0.f), mVisibleAmt(1.f), // default to fully visible @@ -104,6 +105,14 @@ F32 LLLayoutPanel::getCollapseFactor(LLLayoutStack::ELayoutOrientation orientati } } +void LLLayoutPanel::fitToContent() +{ + if (mFitContent) + { + setShape(calcBoundingRect()); + } +} + // // LLLayoutStack // @@ -324,6 +333,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize) for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) { LLLayoutPanel* panelp = (*panel_it); + panelp->fitToContent(); if (panelp->getVisible()) { if (mAnimate) @@ -478,7 +488,9 @@ void LLLayoutStack::updateLayout(BOOL force_resize) { // 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; + 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 diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index d8ef0aeaca..2ed32a2fa9 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -161,14 +161,16 @@ public: min_dim, max_dim; Optional<bool> user_resize, - auto_resize; + auto_resize, + fit_content; Params() : expanded_min_dim("expanded_min_dim", 0), min_dim("min_dim", 0), max_dim("max_dim", 0), user_resize("user_resize", true), - auto_resize("auto_resize", true) + auto_resize("auto_resize", true), + fit_content("fit_content", false) { addSynonym(min_dim, "min_width"); addSynonym(min_dim, "min_height"); @@ -206,18 +208,20 @@ protected: LLLayoutPanel(const Params& p); F32 getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation); + void fitToContent(); - 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; + bool mFitContent; + F32 mVisibleAmt; + F32 mCollapseAmt; class LLResizeBar* mResizeBar; - F32 mVisibleAmt; - F32 mCollapseAmt; }; 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.cpp b/indra/llui/llnotifications.cpp index 6085c61f9a..ffe5908a9d 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -245,7 +245,6 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica LLParamSDParser parser; parser.writeSD(mFormData, p.form_elements); - mFormData = mFormData[""]; if (!mFormData.isArray()) { // change existing contents to a one element array diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h index eff572b553..ab777d37a5 100644 --- a/indra/llui/llnotificationtemplate.h +++ b/indra/llui/llnotificationtemplate.h @@ -88,10 +88,10 @@ struct LLNotificationTemplate { private: // this idiom allows - // <notification unique="true"> + // <notification> <unique/> </notification> // as well as // <notification> <unique> <context></context> </unique>... - Optional<bool> dummy_val; + Flag dummy_val; public: Multiple<UniquenessContext> contexts; diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index b44b4c36b6..fe3f688fc5 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -223,6 +223,15 @@ BOOL LLScrollContainer::handleKeyHere(KEY key, MASK mask) return FALSE; } +BOOL LLScrollContainer::handleUnicodeCharHere(llwchar uni_char) +{ + if (mScrolledView && mScrolledView->handleUnicodeCharHere(uni_char)) + { + return TRUE; + } + return FALSE; +} + BOOL LLScrollContainer::handleScrollWheel( S32 x, S32 y, S32 clicks ) { // Give event to my child views - they may have scroll bars diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h index 46a71a7e30..3aa79cc255 100644 --- a/indra/llui/llscrollcontainer.h +++ b/indra/llui/llscrollcontainer.h @@ -103,6 +103,7 @@ public: // LLView functionality virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); virtual BOOL handleKeyHere(KEY key, MASK mask); + virtual BOOL handleUnicodeCharHere(llwchar uni_char); virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks ); virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp index 9ad13054cb..04919e6991 100644 --- a/indra/llui/llsdparam.cpp +++ b/indra/llui/llsdparam.cpp @@ -183,7 +183,7 @@ LLSD* LLParamSDParser::getSDWriteNode(const parser_t::name_stack_t& name_stack) } } - LLSD* child_sd = &(*sd_to_write)[it->first]; + LLSD* child_sd = it->first.empty() ? sd_to_write : &(*sd_to_write)[it->first]; if (child_sd->isArray()) { diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp new file mode 100644 index 0000000000..8249df3e9d --- /dev/null +++ b/indra/llui/lltoolbar.cpp @@ -0,0 +1,505 @@ +/** + * @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 "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), + min_button_width("min_button_width", 0), + max_button_width("max_button_width", S32_MAX), + button_height("button_height"), + 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), + mMinButtonWidth(llmin(p.min_button_width(), p.max_button_width())), + mMaxButtonWidth(llmax(p.max_button_width(), p.min_button_width())), + mButtonHeight(p.button_height), + 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::Registrar& commit_reg = LLUICtrl::CommitCallbackRegistry::defaultRegistrar(); + commit_reg.add("Toolbars.EnableSetting", boost::bind(&LLToolBar::onSettingEnable, this, _2)); + + LLUICtrl::EnableCallbackRegistry::Registrar& enable_reg = LLUICtrl::EnableCallbackRegistry::defaultRegistrar(); + 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; + } + + // Remove this instance's bindings + commit_reg.remove("Toolbars.EnableSetting"); + enable_reg.remove("Toolbars.CheckSetting"); + } +} + +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; + center_panel_p.fit_content = true; + 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)); + + mNeedsLayout = true; +} + +bool LLToolBar::addCommand(const LLCommandId& commandId) +{ + LLCommand * command = LLCommandManager::instance().getCommand(commandId); + + bool add_command = (command != NULL); + + if (add_command) + { + mButtonCommands.push_back(commandId); + createButtons(); + } + + return add_command; +} + +bool LLToolBar::hasCommand(const LLCommandId& commandId) const +{ + bool has_command = false; + + if (commandId != LLCommandId::null) + { + for (std::list<LLCommandId>::const_iterator cmd = mButtonCommands.begin(); cmd != mButtonCommands.end(); ++cmd) + { + if ((*cmd) == commandId) + { + has_command = true; + break; + } + } + } + + return has_command; +} + +bool LLToolBar::enableCommand(const LLCommandId& commandId, bool enabled) +{ + LLButton * command_button = NULL; + + if (commandId != LLCommandId::null) + { + command_button = mButtonPanel->findChild<LLButton>(commandId.name()); + + if (command_button) + { + command_button->setEnabled(enabled); + } + } + + return (command_button != NULL); +} + +BOOL LLToolBar::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + BOOL handle_it_here = !mReadOnly; + + 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_and_labels") + { + 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(); + + const ButtonType current_button_type = mButtonType; + + if (setting_name == "icons_and_labels") + { + mButtonType = BTNTYPE_ICONS_WITH_TEXT; + } + else if (setting_name == "icons_only") + { + mButtonType = BTNTYPE_ICONS_ONLY; + } + + if(current_button_type != mButtonType) + { + 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(llclamp(button->getRect().getWidth(), mMinButtonWidth, mMaxButtonWidth), max_row_girth); + } + else // VERTICAL + { + button->reshape(max_row_girth, button->getRect().getHeight()); + } + } +} + +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(mMinButtonWidth, mButtonHeight); + button->autoResize(); + + S32 button_clamped_width = llclamp(button->getRect().getWidth(), mMinButtonWidth, mMaxButtonWidth); + 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 = llclamp(max_row_girth, mMinButtonWidth, mMaxButtonWidth); + } + + // 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); + } + + // 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() +{ + updateLayoutAsNeeded(); + 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(); + + BOOST_FOREACH(LLCommandId& command_id, mButtonCommands) + { + LLCommand* commandp = LLCommandManager::instance().getCommand(command_id); + if (!commandp) continue; + + LLToolBarButton::Params button_p; + button_p.label = LLTrans::getString(commandp->labelRef()); + button_p.image_overlay = LLUI::getUIImage(commandp->icon()); + button_p.overwriteFrom(mButtonParams[mButtonType]); + LLToolBarButton* button = LLUICtrlFactory::create<LLToolBarButton>(button_p); + + mButtons.push_back(button); + mButtonPanel->addChild(button); + } + + mNeedsLayout = true; +} + diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h new file mode 100644 index 0000000000..75ae499a3d --- /dev/null +++ b/indra/llui/lltoolbar.h @@ -0,0 +1,169 @@ +/** + * @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" + + +class LLToolBarButton : public LLButton +{ +public: + struct Params : public LLInitParam::Block<Params, LLButton::Params> + { + }; + + LLToolBarButton(const Params& p) : LLButton(p) {} +}; + + +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> min_button_width, + max_button_width, + button_height; + + 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); + BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + + bool addCommand(const LLCommandId& commandId); + bool hasCommand(const LLCommandId& commandId) const; + bool enableCommand(const LLCommandId& commandId, bool enabled); + +protected: + friend class LLUICtrlFactory; + LLToolBar(const Params&); + ~LLToolBar(); + + void initFromParams(const Params&); + +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; + std::list<LLCommandId> mButtonCommands; + LLToolBarEnums::ButtonType mButtonType; + LLLayoutStack* mCenteringStack; + LLLayoutStack* mWrapStack; + LLPanel* mButtonPanel; + LLToolBarEnums::SideType mSideType; + + bool mWrap; + bool mNeedsLayout; + S32 mMinButtonWidth, + mMaxButtonWidth, + mButtonHeight, + mPadLeft, + mPadRight, + mPadTop, + mPadBottom, + mPadBetween; + + LLToolBarButton::Params mButtonParams[LLToolBarEnums::BTNTYPE_COUNT]; + + LLHandle<class LLContextMenu> mPopupMenuHandle; +}; + + +#endif // LL_LLTOOLBAR_H diff --git a/indra/llui/lltoolbarview.cpp b/indra/llui/lltoolbarview.cpp new file mode 100644 index 0000000000..7047cca948 --- /dev/null +++ b/indra/llui/lltoolbarview.cpp @@ -0,0 +1,223 @@ +/** + * @file lltoolbarview.cpp + * @author Merov Linden + * @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 "lltoolbarview.h" + +#include "lldir.h" +#include "llxmlnode.h" +#include "lltoolbar.h" +#include "llbutton.h" + +#include <boost/foreach.hpp> + +LLToolBarView* gToolBarView = NULL; + +static LLDefaultChildRegistry::Register<LLToolBarView> r("toolbar_view"); + +LLToolBarView::Toolbar::Toolbar() +: commands("command") +{} + +LLToolBarView::ToolbarSet::ToolbarSet() +: left_toolbar("left_toolbar"), + right_toolbar("right_toolbar"), + bottom_toolbar("bottom_toolbar") +{} + +bool LLToolBarView::load() +{ + LLToolBarView::ToolbarSet toolbar_set; + + // Load the default toolbars.xml file + // *TODO : pick up the user's toolbar setting if existing + std::string toolbar_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "toolbars.xml"); + + LLXMLNodePtr root; + if(!LLXMLNode::parseFile(toolbar_file, root, NULL)) + { + llerrs << "Unable to load toolbars from file: " << toolbar_file << llendl; + return false; + } + if(!root->hasName("toolbars")) + { + llwarns << toolbar_file << " is not a valid toolbars definition file" << llendl; + return false; + } + + // Parse the toolbar settings + LLXUIParser parser; + parser.readXUI(root, toolbar_set, toolbar_file); + if (!toolbar_set.validateBlock()) + { + llerrs << "Unable to validate toolbars from file: " << toolbar_file << llendl; + return false; + } + + // Add commands to each toolbar + // *TODO: factorize that code : tricky with Blocks though, simple lexical approach fails + LLCommandManager& mgr = LLCommandManager::instance(); + + if (toolbar_set.left_toolbar.isProvided() && mToolbarLeft) + { + BOOST_FOREACH(LLCommandId::Params& command, toolbar_set.left_toolbar.commands) + { + LLCommandId* commandId = new LLCommandId(command); + if (mgr.getCommand(*commandId)) + { + mToolbarLeft->addCommand(*commandId); + } + else + { + llwarns << "Toolbars creation : the command " << commandId->name() << " cannot be found in the command manager" << llendl; + } + } + } + if (toolbar_set.right_toolbar.isProvided() && mToolbarRight) + { + BOOST_FOREACH(LLCommandId::Params& command, toolbar_set.right_toolbar.commands) + { + LLCommandId* commandId = new LLCommandId(command); + if (mgr.getCommand(*commandId)) + { + mToolbarRight->addCommand(*commandId); + } + else + { + llwarns << "Toolbars creation : the command " << commandId->name() << " cannot be found in the command manager" << llendl; + } + } + } + if (toolbar_set.bottom_toolbar.isProvided() && mToolbarBottom) + { + BOOST_FOREACH(LLCommandId::Params& command, toolbar_set.bottom_toolbar.commands) + { + LLCommandId* commandId = new LLCommandId(command); + if (mgr.getCommand(*commandId)) + { + mToolbarBottom->addCommand(*commandId); + } + else + { + llwarns << "Toolbars creation : the command " << commandId->name() << " cannot be found in the command manager" << llendl; + } + } + } + return true; +} + +LLToolBarView::LLToolBarView(const LLToolBarView::Params& p) +: LLUICtrl(p), + mToolbarLeft(NULL), + mToolbarRight(NULL), + mToolbarBottom(NULL) +{ +} + +void LLToolBarView::initFromParams(const LLToolBarView::Params& p) +{ + // Initialize the base object + LLUICtrl::initFromParams(p); +} + +LLToolBarView::~LLToolBarView() +{ +} + +BOOL LLToolBarView::postBuild() +{ + mToolbarLeft = getChild<LLToolBar>("toolbar_left"); + mToolbarRight = getChild<LLToolBar>("toolbar_right"); + mToolbarBottom = getChild<LLToolBar>("toolbar_bottom"); + + // Load the toolbars from the settings + load(); + + return TRUE; +} + +bool LLToolBarView::hasCommand(const LLCommandId& commandId) const +{ + bool has_command = false; + if (mToolbarLeft && !has_command) + { + has_command = mToolbarLeft->hasCommand(commandId); + } + if (mToolbarRight && !has_command) + { + has_command = mToolbarRight->hasCommand(commandId); + } + if (mToolbarBottom && !has_command) + { + has_command = mToolbarBottom->hasCommand(commandId); + } + return has_command; +} + +void LLToolBarView::draw() +{ + static bool debug_print = true; + static S32 old_width = 0; + static S32 old_height = 0; + + //LLPanel* sizer_left = getChild<LLPanel>("sizer_left"); + + LLRect bottom_rect, left_rect, right_rect; + + if (mToolbarBottom) mToolbarBottom->localRectToOtherView(mToolbarBottom->getLocalRect(), &bottom_rect, this); + if (mToolbarLeft) mToolbarLeft->localRectToOtherView(mToolbarLeft->getLocalRect(), &left_rect, this); + if (mToolbarRight) mToolbarRight->localRectToOtherView(mToolbarRight->getLocalRect(), &right_rect, this); + + + if ((old_width != getRect().getWidth()) || (old_height != getRect().getHeight())) + debug_print = true; + if (debug_print) + { + LLRect ctrl_rect = getRect(); + llinfos << "Merov debug : draw control rect = " << ctrl_rect.mLeft << ", " << ctrl_rect.mTop << ", " << ctrl_rect.mRight << ", " << ctrl_rect.mBottom << llendl; + llinfos << "Merov debug : draw bottom rect = " << bottom_rect.mLeft << ", " << bottom_rect.mTop << ", " << bottom_rect.mRight << ", " << bottom_rect.mBottom << llendl; + llinfos << "Merov debug : draw left rect = " << left_rect.mLeft << ", " << left_rect.mTop << ", " << left_rect.mRight << ", " << left_rect.mBottom << llendl; + llinfos << "Merov debug : draw right rect = " << right_rect.mLeft << ", " << right_rect.mTop << ", " << right_rect.mRight << ", " << right_rect.mBottom << llendl; + old_width = ctrl_rect.getWidth(); + old_height = ctrl_rect.getHeight(); + debug_print = false; + } + // Debug draw + LLColor4 back_color = LLColor4::blue; + LLColor4 back_color_vert = LLColor4::red; + LLColor4 back_color_hori = LLColor4::yellow; + back_color[VALPHA] = 0.5f; + back_color_hori[VALPHA] = 0.5f; + back_color_vert[VALPHA] = 0.5f; + //gl_rect_2d(getLocalRect(), back_color, TRUE); + gl_rect_2d(bottom_rect, back_color_hori, TRUE); + gl_rect_2d(left_rect, back_color_vert, TRUE); + gl_rect_2d(right_rect, back_color_vert, TRUE); + + LLUICtrl::draw(); +} diff --git a/indra/llui/lltoolbarview.h b/indra/llui/lltoolbarview.h new file mode 100644 index 0000000000..0f16b89ecc --- /dev/null +++ b/indra/llui/lltoolbarview.h @@ -0,0 +1,90 @@ +/** + * @file lltoolbarview.h + * @author Merov Linden + * @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_LLTOOLBARVIEW_H +#define LL_LLTOOLBARVIEW_H + +#include "lluictrl.h" +#include "lltoolbar.h" +#include "llcommandmanager.h" + +class LLUICtrlFactory; + +// Parent of all LLToolBar + +class LLToolBarView : public LLUICtrl +{ +public: + // Xui structure of the toolbar panel + struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> {}; + + // Note: valid children for LLToolBarView are stored in this registry + typedef LLDefaultChildRegistry child_registry_t; + + // Xml structure of the toolbars.xml setting + // Those live in a toolbars.xml found in app_settings (for the default) and in + // the user folder for the user specific (saved) settings + struct Toolbar : public LLInitParam::Block<Toolbar> + { + Multiple<LLCommandId::Params> commands; + Toolbar(); + }; + struct ToolbarSet : public LLInitParam::Block<ToolbarSet> + { + Optional<Toolbar> left_toolbar, + right_toolbar, + bottom_toolbar; + ToolbarSet(); + }; + + // Derived methods + virtual ~LLToolBarView(); + virtual BOOL postBuild(); + virtual void draw(); + + // Toolbar view interface with the rest of the world + bool hasCommand(const LLCommandId& commandId) const; + +protected: + friend class LLUICtrlFactory; + LLToolBarView(const Params&); + + void initFromParams(const Params&); + +private: + // Loads the toolbars from the existing user or default settings + bool load(); // return false if load fails + + // Pointers to the toolbars handled by the toolbar view + LLToolBar* mToolbarLeft; + LLToolBar* mToolbarRight; + LLToolBar* mToolbarBottom; +}; + +extern LLToolBarView* gToolBarView; + +#endif // LL_LLTOOLBARVIEW_H diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 58ba9e05f5..4f129ccfba 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() diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index f0ba7fc7d7..71c38237c1 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::BaseBlock, DUMMY> : public LLSingleton<ParamDefaults<LLInitParam::BaseBlock, DUMMY> > + class ParamDefaults<LLInitParam::BaseBlockWithFlags, DUMMY> : public LLSingleton<ParamDefaults<LLInitParam::BaseBlockWithFlags, DUMMY> > { public: - const LLInitParam::BaseBlock& get() { return mBaseBlock; } + const LLInitParam::BaseBlockWithFlags& get() { return mBaseBlock; } private: - LLInitParam::BaseBlock mBaseBlock; + LLInitParam::BaseBlockWithFlags 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..7a1b2e4ba0 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -482,7 +482,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(), |