diff options
Diffstat (limited to 'indra/llui')
-rw-r--r-- | indra/llui/llbutton.cpp | 20 | ||||
-rw-r--r-- | indra/llui/llbutton.h | 5 | ||||
-rw-r--r-- | indra/llui/llcommandmanager.cpp | 8 | ||||
-rw-r--r-- | indra/llui/llcommandmanager.h | 16 | ||||
-rw-r--r-- | indra/llui/llfloater.cpp | 27 | ||||
-rw-r--r-- | indra/llui/llfloater.h | 2 | ||||
-rw-r--r-- | indra/llui/llfloaterreg.cpp | 6 | ||||
-rw-r--r-- | indra/llui/llhelp.h | 1 | ||||
-rw-r--r-- | indra/llui/llnotifications.cpp | 72 | ||||
-rw-r--r-- | indra/llui/llresizehandle.cpp | 12 | ||||
-rw-r--r-- | indra/llui/llresizehandle.h | 7 | ||||
-rw-r--r-- | indra/llui/llsdparam.cpp | 264 | ||||
-rw-r--r-- | indra/llui/llsdparam.h | 68 | ||||
-rw-r--r-- | indra/llui/lltoolbar.cpp | 89 | ||||
-rw-r--r-- | indra/llui/lltoolbar.h | 18 | ||||
-rw-r--r-- | indra/llui/tests/llurlentry_stub.cpp | 2 | ||||
-rw-r--r-- | indra/llui/tests/llurlentry_test.cpp | 1 | ||||
-rw-r--r-- | indra/llui/tests/llurlmatch_test.cpp | 4 |
18 files changed, 367 insertions, 255 deletions
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 68cb5164b6..2e9c7a5d3d 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -296,6 +296,24 @@ void LLButton::onCommit() LLUICtrl::onCommit(); } +boost::signals2::connection LLButton::setClickedCallback(const CommitCallbackParam& cb) +{ + return setClickedCallback(initCommitCallback(cb)); +} +boost::signals2::connection LLButton::setMouseDownCallback(const CommitCallbackParam& cb) +{ + return setMouseDownCallback(initCommitCallback(cb)); +} +boost::signals2::connection LLButton::setMouseUpCallback(const CommitCallbackParam& cb) +{ + return setMouseUpCallback(initCommitCallback(cb)); +} +boost::signals2::connection LLButton::setHeldDownCallback(const CommitCallbackParam& cb) +{ + return setHeldDownCallback(initCommitCallback(cb)); +} + + boost::signals2::connection LLButton::setClickedCallback( const commit_signal_t::slot_type& cb ) { if (!mCommitSignal) mCommitSignal = new commit_signal_t(); @@ -1002,7 +1020,7 @@ void LLButton::resize(LLUIString label) if (mImageOverlay) { S32 overlay_width = mImageOverlay->getWidth(); - F32 scale_factor = getRect().getHeight() / (F32)mImageOverlay->getHeight(); + F32 scale_factor = (getRect().getHeight() - (mImageOverlayBottomPad + mImageOverlayTopPad)) / (F32)mImageOverlay->getHeight(); overlay_width = llround((F32)overlay_width * scale_factor); switch(mImageOverlayAlignment) diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index a0a7b4e372..ba0345f610 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -170,6 +170,11 @@ public: void setUseEllipses( BOOL use_ellipses ) { mUseEllipses = use_ellipses; } + boost::signals2::connection setClickedCallback(const CommitCallbackParam& cb); + boost::signals2::connection setMouseDownCallback(const CommitCallbackParam& cb); + boost::signals2::connection setMouseUpCallback(const CommitCallbackParam& cb); + boost::signals2::connection setHeldDownCallback(const CommitCallbackParam& cb); + boost::signals2::connection setClickedCallback( const commit_signal_t::slot_type& cb ); // mouse down and up within button boost::signals2::connection setMouseDownCallback( const commit_signal_t::slot_type& cb ); boost::signals2::connection setMouseUpCallback( const commit_signal_t::slot_type& cb ); // mouse up, EVEN IF NOT IN BUTTON diff --git a/indra/llui/llcommandmanager.cpp b/indra/llui/llcommandmanager.cpp index 9ce7533e1b..128ba609cb 100644 --- a/indra/llui/llcommandmanager.cpp +++ b/indra/llui/llcommandmanager.cpp @@ -41,7 +41,7 @@ // LLCommandId class // -const LLCommandId LLCommandId::null("null command"); +const LLCommandId LLCommandId::null = LLCommandId(); // // LLCommand class @@ -55,6 +55,8 @@ LLCommand::Params::Params() , tooltip_ref("tooltip_ref") , execute_function("execute_function") , execute_parameters("execute_parameters") + , execute_stop_function("execute_stop_function") + , execute_stop_parameters("execute_stop_parameters") , is_enabled_function("is_enabled_function") , is_enabled_parameters("is_enabled_parameters") , is_running_function("is_running_function") @@ -72,6 +74,8 @@ LLCommand::LLCommand(const LLCommand::Params& p) , mTooltipRef(p.tooltip_ref) , mExecuteFunction(p.execute_function) , mExecuteParameters(p.execute_parameters) + , mExecuteStopFunction(p.execute_stop_function) + , mExecuteStopParameters(p.execute_stop_parameters) , mIsEnabledFunction(p.is_enabled_function) , mIsEnabledParameters(p.is_enabled_parameters) , mIsRunningFunction(p.is_running_function) @@ -152,7 +156,7 @@ bool LLCommandManager::load() if (!commandsParams.validateBlock()) { - llerrs << "Unable to validate commands param block from file: " << commands_file << llendl; + llerrs << "Invalid commands file: " << commands_file << llendl; return false; } diff --git a/indra/llui/llcommandmanager.h b/indra/llui/llcommandmanager.h index 8f9f956ec7..9b93ab735a 100644 --- a/indra/llui/llcommandmanager.h +++ b/indra/llui/llcommandmanager.h @@ -50,6 +50,12 @@ public: {} }; + LLCommandId() + : mName("null command") + { + mUUID = LLUUID::generateNewID(mName); + } + LLCommandId(const std::string& name) : mName(name) { @@ -65,7 +71,6 @@ public: LLCommandId(const LLUUID& uuid) : mName(""), mUUID(uuid) - { } @@ -111,6 +116,9 @@ public: Mandatory<std::string> execute_function; Optional<LLSD> execute_parameters; + Optional<std::string> execute_stop_function; + Optional<LLSD> execute_stop_parameters; + Optional<std::string> is_enabled_function; Optional<LLSD> is_enabled_parameters; @@ -134,6 +142,9 @@ public: const std::string& executeFunctionName() const { return mExecuteFunction; } const LLSD& executeParameters() const { return mExecuteParameters; } + const std::string& executeStopFunctionName() const { return mExecuteStopFunction; } + const LLSD& executeStopParameters() const { return mExecuteStopParameters; } + const std::string& isEnabledFunctionName() const { return mIsEnabledFunction; } const LLSD& isEnabledParameters() const { return mIsEnabledParameters; } @@ -154,6 +165,9 @@ private: std::string mExecuteFunction; LLSD mExecuteParameters; + std::string mExecuteStopFunction; + LLSD mExecuteStopParameters; + std::string mIsEnabledFunction; LLSD mIsEnabledParameters; diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index c28bcc2ec9..90c41e99dc 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -459,15 +459,24 @@ void LLFloater::layoutResizeCtrls() mResizeHandle[3]->setRect(rect); } -void LLFloater::enableResizeCtrls(bool enable) +void LLFloater::enableResizeCtrls(bool enable, bool width, bool height) { + mResizeBar[LLResizeBar::LEFT]->setVisible(enable && width); + mResizeBar[LLResizeBar::LEFT]->setEnabled(enable && width); + + mResizeBar[LLResizeBar::TOP]->setVisible(enable && height); + mResizeBar[LLResizeBar::TOP]->setEnabled(enable && height); + + mResizeBar[LLResizeBar::RIGHT]->setVisible(enable && width); + mResizeBar[LLResizeBar::RIGHT]->setEnabled(enable && width); + + mResizeBar[LLResizeBar::BOTTOM]->setVisible(enable && height); + mResizeBar[LLResizeBar::BOTTOM]->setEnabled(enable && height); + for (S32 i = 0; i < 4; ++i) { - mResizeBar[i]->setVisible(enable); - mResizeBar[i]->setEnabled(enable); - - mResizeHandle[i]->setVisible(enable); - mResizeHandle[i]->setEnabled(enable); + mResizeHandle[i]->setVisible(enable && width && height); + mResizeHandle[i]->setEnabled(enable && width && height); } } @@ -840,9 +849,9 @@ void LLFloater::applyRectControl() if (mRectControl.size() > 1) { const LLRect& rect = getControlGroup()->getRect(mRectControl); - if (rect.getWidth() > 0 && rect.getHeight() > 0) + if (rect.notEmpty()) { - translate( rect.mLeft - getRect().mLeft, rect.mBottom - getRect().mBottom); + setOrigin(rect.mLeft, rect.mBottom); if (mResizable) { reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight())); @@ -2549,7 +2558,7 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out } // move window fully onscreen - if (floater->translateIntoRect( getLocalRect(), allow_partial_outside )) + if (floater->translateIntoRect( getSnapRect(), allow_partial_outside )) { floater->clearSnapTarget(); } diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 5aff542049..af9665e599 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -291,6 +291,7 @@ public: void updateTransparency(ETypeTransparency transparency_type); + void enableResizeCtrls(bool enable, bool width = true, bool height = true); protected: virtual void applySavedVariables(); @@ -340,7 +341,6 @@ private: BOOL offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButton index); void addResizeCtrls(); void layoutResizeCtrls(); - void enableResizeCtrls(bool enable); void addDragHandle(); void layoutDragHandle(); // repair layout diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp index d0ae9413a3..ae06eb74ac 100644 --- a/indra/llui/llfloaterreg.cpp +++ b/indra/llui/llfloaterreg.cpp @@ -110,7 +110,11 @@ LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key) int index = list.size(); res = build_func(key); - + if (!res) + { + llwarns << "Failed to build floater type: '" << name << "'." << llendl; + return NULL; + } bool success = res->buildFromFile(xui_file, NULL); if (!success) { diff --git a/indra/llui/llhelp.h b/indra/llui/llhelp.h index 83317bd03c..1726347a78 100644 --- a/indra/llui/llhelp.h +++ b/indra/llui/llhelp.h @@ -32,6 +32,7 @@ class LLHelp { public: virtual void showTopic(const std::string &topic) = 0; + virtual std::string getURL(const std::string &topic) = 0; // return default (fallback) topic name suitable for showTopic() virtual std::string defaultTopic() = 0; // return topic to use before the user logs in diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index ffe5908a9d..8f7025a9a6 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -46,6 +46,7 @@ #include <algorithm> #include <boost/regex.hpp> +#include <boost/foreach.hpp> const std::string NOTIFICATION_PERSIST_VERSION = "0.93"; @@ -416,23 +417,17 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par mSoundEffect = LLUUID(LLUI::sSettingGroups["config"]->getString(p.sound)); } - for(LLInitParam::ParamIterator<LLNotificationTemplate::UniquenessContext>::const_iterator it = p.unique.contexts.begin(), - end_it = p.unique.contexts.end(); - it != end_it; - ++it) + BOOST_FOREACH(const LLNotificationTemplate::UniquenessContext& context, p.unique.contexts) { - mUniqueContext.push_back(it->value); + mUniqueContext.push_back(context.value); } lldebugs << "notification \"" << mName << "\": tag count is " << p.tags.size() << llendl; - for(LLInitParam::ParamIterator<LLNotificationTemplate::Tag>::const_iterator it = p.tags.begin(), - end_it = p.tags.end(); - it != end_it; - ++it) + BOOST_FOREACH(const LLNotificationTemplate::Tag& tag, p.tags) { - lldebugs << " tag \"" << std::string(it->value) << "\"" << llendl; - mTags.push_back(it->value); + lldebugs << " tag \"" << std::string(tag.value) << "\"" << llendl; + mTags.push_back(tag.value); } mForm = LLNotificationFormPtr(new LLNotificationForm(p.name, p.form_ref.form)); @@ -1397,14 +1392,12 @@ void replaceFormText(LLNotificationForm::Params& form, const std::string& patter { form.ignore.text = replace; } - for (LLInitParam::ParamIterator<LLNotificationForm::FormElement>::iterator it = form.form_elements.elements.begin(), - end_it = form.form_elements.elements.end(); - it != end_it; - ++it) + + BOOST_FOREACH(LLNotificationForm::FormElement& element, form.form_elements.elements) { - if (it->button.isChosen() && it->button.text() == pattern) + if (element.button.isChosen() && element.button.text() == pattern) { - it->button.text = replace; + element.button.text = replace; } } } @@ -1453,48 +1446,42 @@ bool LLNotifications::loadTemplates() mTemplates.clear(); - for(LLInitParam::ParamIterator<LLNotificationTemplate::GlobalString>::const_iterator it = params.strings.begin(), end_it = params.strings.end(); - it != end_it; - ++it) + BOOST_FOREACH(LLNotificationTemplate::GlobalString& string, params.strings) { - mGlobalStrings[it->name] = it->value; + mGlobalStrings[string.name] = string.value; } std::map<std::string, LLNotificationForm::Params> form_templates; - for(LLInitParam::ParamIterator<LLNotificationTemplate::Template>::const_iterator it = params.templates.begin(), end_it = params.templates.end(); - it != end_it; - ++it) + BOOST_FOREACH(LLNotificationTemplate::Template& notification_template, params.templates) { - form_templates[it->name] = it->form; + form_templates[notification_template.name] = notification_template.form; } - for(LLInitParam::ParamIterator<LLNotificationTemplate::Params>::iterator it = params.notifications.begin(), end_it = params.notifications.end(); - it != end_it; - ++it) + BOOST_FOREACH(LLNotificationTemplate::Params& notification, params.notifications) { - if (it->form_ref.form_template.isChosen()) + if (notification.form_ref.form_template.isChosen()) { // replace form contents from template - it->form_ref.form = form_templates[it->form_ref.form_template.name]; - if(it->form_ref.form_template.yes_text.isProvided()) + notification.form_ref.form = form_templates[notification.form_ref.form_template.name]; + if(notification.form_ref.form_template.yes_text.isProvided()) { - replaceFormText(it->form_ref.form, "$yestext", it->form_ref.form_template.yes_text); + replaceFormText(notification.form_ref.form, "$yestext", notification.form_ref.form_template.yes_text); } - if(it->form_ref.form_template.no_text.isProvided()) + if(notification.form_ref.form_template.no_text.isProvided()) { - replaceFormText(it->form_ref.form, "$notext", it->form_ref.form_template.no_text); + replaceFormText(notification.form_ref.form, "$notext", notification.form_ref.form_template.no_text); } - if(it->form_ref.form_template.cancel_text.isProvided()) + if(notification.form_ref.form_template.cancel_text.isProvided()) { - replaceFormText(it->form_ref.form, "$canceltext", it->form_ref.form_template.cancel_text); + replaceFormText(notification.form_ref.form, "$canceltext", notification.form_ref.form_template.cancel_text); } - if(it->form_ref.form_template.ignore_text.isProvided()) + if(notification.form_ref.form_template.ignore_text.isProvided()) { - replaceFormText(it->form_ref.form, "$ignoretext", it->form_ref.form_template.ignore_text); + replaceFormText(notification.form_ref.form, "$ignoretext", notification.form_ref.form_template.ignore_text); } } - mTemplates[it->name] = LLNotificationTemplatePtr(new LLNotificationTemplate(*it)); + mTemplates[notification.name] = LLNotificationTemplatePtr(new LLNotificationTemplate(notification)); } return true; @@ -1517,12 +1504,9 @@ bool LLNotifications::loadVisibilityRules() mVisibilityRules.clear(); - for(LLInitParam::ParamIterator<LLNotificationVisibilityRule::Rule>::iterator it = params.rules.begin(), - end_it = params.rules.end(); - it != end_it; - ++it) + BOOST_FOREACH(LLNotificationVisibilityRule::Rule& rule, params.rules) { - mVisibilityRules.push_back(LLNotificationVisibilityRulePtr(new LLNotificationVisibilityRule(*it))); + mVisibilityRules.push_back(LLNotificationVisibilityRulePtr(new LLNotificationVisibilityRule(rule))); } return true; diff --git a/indra/llui/llresizehandle.cpp b/indra/llui/llresizehandle.cpp index 942e84eeb6..c3a51c36c9 100644 --- a/indra/llui/llresizehandle.cpp +++ b/indra/llui/llresizehandle.cpp @@ -55,8 +55,6 @@ 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) @@ -179,11 +177,6 @@ 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 ) @@ -191,11 +184,6 @@ 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 5cfe3fb63c..7541b9e6c0 100644 --- a/indra/llui/llresizehandle.h +++ b/indra/llui/llresizehandle.h @@ -55,10 +55,7 @@ public: virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); 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 ); @@ -69,9 +66,7 @@ private: LLCoordGL mLastMouseDir; LLPointer<LLUIImage> mImage; S32 mMinWidth; - S32 mMaxWidth; S32 mMinHeight; - S32 mMaxHeight; const ECorner mCorner; }; diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp index 4b69360e33..242b1fca7f 100644 --- a/indra/llui/llsdparam.cpp +++ b/indra/llui/llsdparam.cpp @@ -34,6 +34,7 @@ static LLInitParam::Parser::parser_read_func_map_t sReadFuncs; static LLInitParam::Parser::parser_write_func_map_t sWriteFuncs; static LLInitParam::Parser::parser_inspect_func_map_t sInspectFuncs; +static const LLSD NO_VALUE_MARKER; // // LLParamSDParser @@ -60,29 +61,34 @@ LLParamSDParser::LLParamSDParser() } // special case handling of U32 due to ambiguous LLSD::assign overload -bool LLParamSDParser::writeU32Param(LLParamSDParser::parser_t& parser, const void* val_ptr, const parser_t::name_stack_t& name_stack) +bool LLParamSDParser::writeU32Param(LLParamSDParser::parser_t& parser, const void* val_ptr, parser_t::name_stack_t& name_stack) { LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser); if (!sdparser.mWriteRootSD) return false; - LLSD* sd_to_write = sdparser.getSDWriteNode(name_stack); - if (!sd_to_write) return false; + parser_t::name_stack_range_t range(name_stack.begin(), name_stack.end()); + LLSD& sd_to_write = LLParamSDParserUtilities::getSDWriteNode(*sdparser.mWriteRootSD, range); + sd_to_write.assign((S32)*((const U32*)val_ptr)); - sd_to_write->assign((S32)*((const U32*)val_ptr)); return true; } -bool LLParamSDParser::writeFlag(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, parser_t::name_stack_t& name_stack) { LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser); if (!sdparser.mWriteRootSD) return false; - LLSD* sd_to_write = sdparser.getSDWriteNode(name_stack); - if (!sd_to_write) return false; + parser_t::name_stack_range_t range(name_stack.begin(), name_stack.end()); + LLParamSDParserUtilities::getSDWriteNode(*sdparser.mWriteRootSD, range); return true; } +void LLParamSDParser::submit(LLInitParam::BaseBlock& block, const LLSD& sd, LLInitParam::Parser::name_stack_t& name_stack) +{ + mCurReadSD = &sd; + block.submitValue(name_stack, *this); +} void LLParamSDParser::readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool silent) { @@ -90,7 +96,8 @@ void LLParamSDParser::readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool mNameStack.clear(); setParseSilently(silent); - readSDValues(sd, block); + LLParamSDParserUtilities::readSDValues(boost::bind(&LLParamSDParser::submit, this, boost::ref(block), _1, _2), sd, mNameStack); + //readSDValues(sd, block); } void LLParamSDParser::writeSD(LLSD& sd, const LLInitParam::BaseBlock& block) @@ -100,43 +107,6 @@ void LLParamSDParser::writeSD(LLSD& sd, const LLInitParam::BaseBlock& block) block.serializeBlock(*this); } -const LLSD NO_VALUE_MARKER; - -void LLParamSDParser::readSDValues(const LLSD& sd, LLInitParam::BaseBlock& block) -{ - if (sd.isMap()) - { - for (LLSD::map_const_iterator it = sd.beginMap(); - it != sd.endMap(); - ++it) - { - mNameStack.push_back(make_pair(it->first, newParseGeneration())); - readSDValues(it->second, block); - mNameStack.pop_back(); - } - } - else if (sd.isArray()) - { - for (LLSD::array_const_iterator it = sd.beginArray(); - it != sd.endArray(); - ++it) - { - mNameStack.back().second = newParseGeneration(); - readSDValues(*it, block); - } - } - else if (sd.isUndefined()) - { - mCurReadSD = &NO_VALUE_MARKER; - block.submitValue(mNameStack, *this); - } - else - { - mCurReadSD = &sd; - block.submitValue(mNameStack, *this); - } -} - /*virtual*/ std::string LLParamSDParser::getCurrentElementName() { std::string full_name = "sd"; @@ -150,81 +120,6 @@ void LLParamSDParser::readSDValues(const LLSD& sd, LLInitParam::BaseBlock& block return full_name; } -LLSD* LLParamSDParser::getSDWriteNode(const parser_t::name_stack_t& name_stack) -{ - //TODO: implement nested LLSD writing - LLSD* sd_to_write = mWriteRootSD; - bool new_traversal = false; - for (name_stack_t::const_iterator it = name_stack.begin(), prev_it = mNameStack.begin(); - it != name_stack.end(); - ++it) - { - bool new_array_entry = false; - if (prev_it == mNameStack.end()) - { - new_traversal = true; - } - else - { - if (!new_traversal // have not diverged yet from previous trace - && prev_it->first == it->first // names match - && prev_it->second != it->second) // versions differ - { - // name stacks match, but version numbers differ in last place. - // create a different entry at this point using an LLSD array - new_array_entry = true; - } - if (prev_it->first != it->first // names differ - || prev_it->second != it->second) // versions differ - { - // at this point we have diverged from our last trace - // so any elements referenced here are new - new_traversal = true; - } - } - - LLSD* child_sd = it->first.empty() ? sd_to_write : &(*sd_to_write)[it->first]; - - if (child_sd->isArray()) - { - if (new_traversal) - { - // write to new element at end - sd_to_write = &(*child_sd)[child_sd->size()]; - } - else - { - // write to last of existing elements, or first element if empty - sd_to_write = &(*child_sd)[llmax(0, child_sd->size() - 1)]; - } - } - else - { - if (new_array_entry && !child_sd->isArray()) - { - // copy child contents into first element of an array - LLSD new_array = LLSD::emptyArray(); - new_array.append(*child_sd); - // assign array to slot that previously held the single value - *child_sd = new_array; - // return next element in that array - sd_to_write = &((*child_sd)[1]); - } - else - { - sd_to_write = child_sd; - } - } - if (prev_it != mNameStack.end()) - { - ++prev_it; - } - } - mNameStack = name_stack; - - //llinfos << ll_pretty_print_sd(*mWriteRootSD) << llendl; - return sd_to_write; -} bool LLParamSDParser::readFlag(Parser& parser, void* val_ptr) { @@ -312,3 +207,132 @@ bool LLParamSDParser::readSD(Parser& parser, void* val_ptr) *((LLSD*)val_ptr) = *self.mCurReadSD; return true; } + +// static +LLSD& LLParamSDParserUtilities::getSDWriteNode(LLSD& input, LLInitParam::Parser::name_stack_range_t& name_stack_range) +{ + LLSD* sd_to_write = &input; + + for (LLInitParam::Parser::name_stack_t::iterator it = name_stack_range.first; + it != name_stack_range.second; + ++it) + { + bool new_traversal = it->second; + + LLSD* child_sd = it->first.empty() ? sd_to_write : &(*sd_to_write)[it->first]; + + if (child_sd->isArray()) + { + if (new_traversal) + { + // write to new element at end + sd_to_write = &(*child_sd)[child_sd->size()]; + } + else + { + // write to last of existing elements, or first element if empty + sd_to_write = &(*child_sd)[llmax(0, child_sd->size() - 1)]; + } + } + else + { + if (new_traversal + && child_sd->isDefined() + && !child_sd->isArray()) + { + // copy child contents into first element of an array + LLSD new_array = LLSD::emptyArray(); + new_array.append(*child_sd); + // assign array to slot that previously held the single value + *child_sd = new_array; + // return next element in that array + sd_to_write = &((*child_sd)[1]); + } + else + { + sd_to_write = child_sd; + } + } + it->second = false; + } + + return *sd_to_write; +} + +//static +void LLParamSDParserUtilities::readSDValues(read_sd_cb_t cb, const LLSD& sd, LLInitParam::Parser::name_stack_t& stack) +{ + if (sd.isMap()) + { + for (LLSD::map_const_iterator it = sd.beginMap(); + it != sd.endMap(); + ++it) + { + stack.push_back(make_pair(it->first, true)); + readSDValues(cb, it->second, stack); + stack.pop_back(); + } + } + else if (sd.isArray()) + { + for (LLSD::array_const_iterator it = sd.beginArray(); + it != sd.endArray(); + ++it) + { + stack.back().second = true; + readSDValues(cb, *it, stack); + } + } + else if (sd.isUndefined()) + { + if (!cb.empty()) + { + cb(NO_VALUE_MARKER, stack); + } + } + else + { + if (!cb.empty()) + { + cb(sd, stack); + } + } +} + +//static +void LLParamSDParserUtilities::readSDValues(read_sd_cb_t cb, const LLSD& sd) +{ + LLInitParam::Parser::name_stack_t stack = LLInitParam::Parser::name_stack_t(); + readSDValues(cb, sd, stack); +} +namespace LLInitParam +{ + // LLSD specialization + // block param interface + bool ParamValue<LLSD, TypeValues<LLSD>, false>::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name) + { + LLSD& sd = LLParamSDParserUtilities::getSDWriteNode(mValue, name_stack); + + LLSD::String string; + + if (p.readValue<LLSD::String>(string)) + { + sd = string; + return true; + } + return false; + } + + //static + void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack) + { + p.writeValue<LLSD::String>(sd.asString(), name_stack); + } + + void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeBlock(Parser& p, Parser::name_stack_t name_stack, const BaseBlock* diff_block) const + { + // read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc) + Parser::name_stack_t stack; + LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, stack); + } +} diff --git a/indra/llui/llsdparam.h b/indra/llui/llsdparam.h index a371c28f68..c1cfa98399 100644 --- a/indra/llui/llsdparam.h +++ b/indra/llui/llsdparam.h @@ -29,6 +29,16 @@ #define LL_LLSDPARAM_H #include "llinitparam.h" +#include "boost/function.hpp" + +struct LLParamSDParserUtilities +{ + static LLSD& getSDWriteNode(LLSD& input, LLInitParam::Parser::name_stack_range_t& name_stack_range); + + typedef boost::function<void (const LLSD&, LLInitParam::Parser::name_stack_t&)> read_sd_cb_t; + static void readSDValues(read_sd_cb_t cb, const LLSD& sd, LLInitParam::Parser::name_stack_t& stack); + static void readSDValues(read_sd_cb_t cb, const LLSD& sd); +}; class LLParamSDParser : public LLInitParam::Parser @@ -45,25 +55,23 @@ public: /*virtual*/ std::string getCurrentElementName(); private: - void readSDValues(const LLSD& sd, LLInitParam::BaseBlock& block); + void submit(LLInitParam::BaseBlock& block, const LLSD& sd, LLInitParam::Parser::name_stack_t& name_stack); template<typename T> - static bool writeTypedValue(Parser& parser, const void* val_ptr, const parser_t::name_stack_t& name_stack) + static bool writeTypedValue(Parser& parser, const void* val_ptr, parser_t::name_stack_t& name_stack) { LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser); if (!sdparser.mWriteRootSD) return false; - LLSD* sd_to_write = sdparser.getSDWriteNode(name_stack); - if (!sd_to_write) return false; + LLInitParam::Parser::name_stack_range_t range(name_stack.begin(), name_stack.end()); + LLSD& sd_to_write = LLParamSDParserUtilities::getSDWriteNode(*sdparser.mWriteRootSD, range); - sd_to_write->assign(*((const T*)val_ptr)); + sd_to_write.assign(*((const T*)val_ptr)); return true; } - 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 writeFlag(Parser& parser, const void* value_ptr, const parser_t::name_stack_t& name_stack); + static bool writeU32Param(Parser& parser, const void* value_ptr, parser_t::name_stack_t& name_stack); + static bool writeFlag(Parser& parser, const void* value_ptr, parser_t::name_stack_t& name_stack); static bool readFlag(Parser& parser, void* val_ptr); static bool readS32(Parser& parser, void* val_ptr); @@ -85,29 +93,29 @@ private: template<typename T> class LLSDParamAdapter : public T +{ +public: + LLSDParamAdapter() {} + LLSDParamAdapter(const LLSD& sd) { - public: - LLSDParamAdapter() {} - LLSDParamAdapter(const LLSD& sd) - { - LLParamSDParser parser; - parser.readSD(sd, *this); - } - - operator LLSD() const - { - LLParamSDParser parser; - LLSD sd; - parser.writeSD(sd, *this); - return sd; - } + LLParamSDParser parser; + parser.readSD(sd, *this); + } + + operator LLSD() const + { + LLParamSDParser parser; + LLSD sd; + parser.writeSD(sd, *this); + return sd; + } - LLSDParamAdapter(const T& val) - : T(val) - { - T::operator=(val); - } - }; + LLSDParamAdapter(const T& val) + : T(val) + { + T::operator=(val); + } +}; #endif // LL_LLSDPARAM_H diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp index 1f5fa5f361..e74aab6e21 100644 --- a/indra/llui/lltoolbar.cpp +++ b/indra/llui/lltoolbar.cpp @@ -33,6 +33,7 @@ #include "llcommandmanager.h" #include "llmenugl.h" #include "lltrans.h" +#include "llinventory.h" // uncomment this and remove the one in llui.cpp when there is an external reference to this translation unit // thanks, MSVC! @@ -86,6 +87,7 @@ LLToolBar::Params::Params() pad_right("pad_right"), pad_bottom("pad_bottom"), pad_between("pad_between"), + min_girth("min_girth"), button_panel("button_panel") {} @@ -103,6 +105,7 @@ LLToolBar::LLToolBar(const LLToolBar::Params& p) mPadTop(p.pad_top), mPadBottom(p.pad_bottom), mPadBetween(p.pad_between), + mMinGirth(p.min_girth), mPopupMenuHandle(), mStartDragItemCallback(NULL), mHandleDragItemCallback(NULL), @@ -201,14 +204,16 @@ bool LLToolBar::addCommand(const LLCommandId& commandId, int rank) { LLCommand * command = LLCommandManager::instance().getCommand(commandId); if (!command) return false; - + llinfos << "Merov debug : addCommand, " << commandId.name() << ", " << commandId.uuid() << llendl; + // 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)); + mButtonMap.insert(std::make_pair(commandId.uuid(), button)); + // Insert the command and button in the right place in their respective lists - if ((rank >= mButtonCommands.size()) || (rank < 0)) + if ((rank >= mButtonCommands.size()) || (rank == RANK_NONE)) { // In that case, back load mButtonCommands.push_back(commandId); @@ -235,21 +240,28 @@ bool LLToolBar::addCommand(const LLCommandId& commandId, int rank) return true; } -bool LLToolBar::removeCommand(const LLCommandId& commandId) +// Remove a command from the list +// Returns the rank of the command in the original list so that doing addCommand(id,rank) right after +// a removeCommand(id) would leave the list unchanged. +// Returns RANK_NONE if the command is not found in the list +int LLToolBar::removeCommand(const LLCommandId& commandId) { - if (!hasCommand(commandId)) return false; + if (!hasCommand(commandId)) return RANK_NONE; + llinfos << "Merov debug : removeCommand, " << commandId.name() << ", " << commandId.uuid() << llendl; // First erase the map record - command_id_map::iterator it = mButtonMap.find(commandId); + command_id_map::iterator it = mButtonMap.find(commandId.uuid()); mButtonMap.erase(it); // Now iterate on the commands and buttons to identify the relevant records + int rank = 0; 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; + ++rank; } // Delete the button and erase the command and button records @@ -259,7 +271,7 @@ bool LLToolBar::removeCommand(const LLCommandId& commandId) mNeedsLayout = true; - return true; + return rank; } void LLToolBar::clearCommandsList() @@ -274,7 +286,7 @@ bool LLToolBar::hasCommand(const LLCommandId& commandId) const { if (commandId != LLCommandId::null) { - command_id_map::const_iterator it = mButtonMap.find(commandId); + command_id_map::const_iterator it = mButtonMap.find(commandId.uuid()); return (it != mButtonMap.end()); } @@ -287,7 +299,7 @@ bool LLToolBar::enableCommand(const LLCommandId& commandId, bool enabled) if (commandId != LLCommandId::null) { - command_id_map::iterator it = mButtonMap.find(commandId); + command_id_map::iterator it = mButtonMap.find(commandId.uuid()); if (it != mButtonMap.end()) { it->second->setEnabled(enabled); @@ -382,6 +394,10 @@ void LLToolBar::resizeButtonsInRow(std::vector<LLToolBarButton*>& buttons_in_row } } +// Returns the position of the coordinates as a rank in the button list. +// The rank is the position a tool dropped in (x,y) would assume in the button list. +// The value returned is between 0 and mButtons.size(), 0 being the first element to the left +// (or top) and mButtons.size() the last one to the right (or bottom). int LLToolBar::getRankFromPosition(S32 x, S32 y) { int rank = 0; @@ -505,7 +521,7 @@ void LLToolBar::updateLayoutAsNeeded() 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; @@ -517,6 +533,8 @@ void LLToolBar::updateLayoutAsNeeded() 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 + total_girth = llmax(total_girth,mMinGirth); + max_row_length = llmax(max_row_length, row_running_length - mPadBetween + row_pad_end); resizeButtonsInRow(buttons_in_row, max_row_girth); @@ -618,7 +636,7 @@ void LLToolBar::createButtons() LLToolBarButton* button = createButton(command_id); mButtons.push_back(button); mButtonPanel->addChild(button); - mButtonMap.insert(std::make_pair(command_id, button)); + mButtonMap.insert(std::make_pair(command_id.uuid(), button)); } mNeedsLayout = true; } @@ -641,11 +659,25 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id) if (!mReadOnly) { - LLUICtrl::CommitCallbackParam cbParam; - cbParam.function_name = commandp->executeFunctionName(); - cbParam.parameter = commandp->executeParameters(); + LLUICtrl::CommitCallbackParam executeParam; + executeParam.function_name = commandp->executeFunctionName(); + executeParam.parameter = commandp->executeParameters(); - button->setCommitCallback(cbParam); + // If we have a "stop" function then we map the command to mouse down / mouse up otherwise commit + const std::string& executeStopFunction = commandp->executeStopFunctionName(); + if (executeStopFunction.length() > 0) + { + LLUICtrl::CommitCallbackParam executeStopParam; + executeStopParam.function_name = executeStopFunction; + executeStopParam.parameter = commandp->executeStopParameters(); + + button->setMouseDownCallback(executeParam); + button->setMouseUpCallback(executeStopParam); + } + else + { + button->setCommitCallback(executeParam); + } const std::string& isEnabledFunction = commandp->isEnabledFunctionName(); if (isEnabledFunction.length() > 0) @@ -695,7 +727,7 @@ BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EAcceptance* accept, std::string& tooltip_msg) { - //llinfos << "Merov debug : handleDragAndDrop. drop = " << drop << ", x = " << x << ", y = " << y << llendl; + 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); @@ -709,7 +741,25 @@ BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, *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; + mDragAndDropTarget = false; + + // HACK!!! + if (!isReadOnly() && handled) + { + if (!drop) + { + LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data; + LLAssetType::EType type = inv_item->getType(); + if (type == LLAssetType::AT_WIDGET) + { + LLCommandId dragged_command(inv_item->getUUID()); + int rank = getRankFromPosition(x, y); + removeCommand(dragged_command); + addCommand(dragged_command,rank); + mDragAndDropTarget = true; + } + } + } return handled; } @@ -787,3 +837,8 @@ void LLToolBarButton::onMouseCaptureLost() { mIsDragged = false; } + +void LLToolBarButton::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + LLButton::reshape(mWidthRange.clamp(width), height, called_from_parent); +} diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h index e4534dea5f..d9ea0f57d3 100644 --- a/indra/llui/lltoolbar.h +++ b/indra/llui/lltoolbar.h @@ -47,7 +47,7 @@ class LLToolBarButton : public LLButton public: struct Params : public LLInitParam::Block<Params, LLButton::Params> { - Optional<LLUI::RangeS32> button_width; + Optional<LLUI::RangeS32::Params> button_width; Optional<S32> desired_height; Params() @@ -62,6 +62,8 @@ public: BOOL handleMouseDown(S32 x, S32 y, MASK mask); BOOL handleHover(S32 x, S32 y, MASK mask); + void reshape(S32 width, S32 height, BOOL called_from_parent = true); + void setCommandId(const LLCommandId& id) { mId = id; } void setStartDragCallback(tool_startdrag_callback_t cb) { mStartDragItemCallback = cb; } @@ -141,7 +143,8 @@ public: pad_top, pad_right, pad_bottom, - pad_between; + pad_between, + min_girth; // get rid of this Multiple<LLCommandId::Params> commands; @@ -161,8 +164,10 @@ public: EAcceptance* accept, std::string& tooltip_msg); - bool addCommand(const LLCommandId& commandId, int rank = -1); - bool removeCommand(const LLCommandId& commandId); + static const int RANK_NONE = -1; + + bool addCommand(const LLCommandId& commandId, int rank = RANK_NONE); + int removeCommand(const LLCommandId& commandId); // Returns the rank the removed command was at, RANK_NONE if not found bool hasCommand(const LLCommandId& commandId) const; bool enableCommand(const LLCommandId& commandId, bool enabled); @@ -206,7 +211,7 @@ private: typedef std::list<LLToolBarButton*> toolbar_button_list; toolbar_button_list mButtons; command_id_list_t mButtonCommands; - typedef std::map<LLCommandId, LLToolBarButton*> command_id_map; + typedef std::map<LLUUID, LLToolBarButton*> command_id_map; command_id_map mButtonMap; LLToolBarEnums::ButtonType mButtonType; @@ -221,7 +226,8 @@ private: mPadRight, mPadTop, mPadBottom, - mPadBetween; + mPadBetween, + mMinGirth; LLToolBarButton::Params mButtonParams[LLToolBarEnums::BTNTYPE_COUNT]; diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp index d522123260..c8303bfc89 100644 --- a/indra/llui/tests/llurlentry_stub.cpp +++ b/indra/llui/tests/llurlentry_stub.cpp @@ -124,7 +124,7 @@ namespace LLInitParam { descriptor.mCurrentBlockPtr = this; } - bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation){ return true; } + bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name){ return true; } void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const {} bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_value, S32 max_value) const { return true; } bool BaseBlock::mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; } diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 2f814f4200..c1fb050206 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -72,7 +72,6 @@ S32 LLUIImage::getHeight() const namespace LLInitParam { - S32 Parser::sNextParseGeneration = 0; BlockDescriptor::BlockDescriptor() {} ParamDescriptor::ParamDescriptor(param_handle_t p, merge_func_t merge_func, diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp index fb6a2eabf1..9dbccf125a 100644 --- a/indra/llui/tests/llurlmatch_test.cpp +++ b/indra/llui/tests/llurlmatch_test.cpp @@ -66,8 +66,6 @@ namespace LLInitParam BaseBlock::BaseBlock() {} BaseBlock::~BaseBlock() {} - S32 Parser::sNextParseGeneration = 0; - BlockDescriptor::BlockDescriptor() {} ParamDescriptor::ParamDescriptor(param_handle_t p, merge_func_t merge_func, @@ -98,7 +96,7 @@ namespace LLInitParam mEnclosingBlockOffset = 0x7FFFffff & ((U32)(my_addr - block_addr)); } - bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation){ return true; } + bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name){ return true; } void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const {} bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_count, S32 max_count) const { return true; } bool BaseBlock::mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; } |