diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 239ac5b74..4a64b0044 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -395,8 +395,14 @@ void LLTextBox::initFromXML(LLXMLNodePtr node, LLView* parent) LLFontGL* font = LLView::selectFont(node); if(font) mFontGL = font; - - setText(node->getTextContents()); + + if (node->hasAttribute("value")) + { + std::string text; + node->getAttributeString("value", text); + setText(text); + } + else setText(node->getTextContents()); LLFontGL::HAlign halign = LLView::selectFontHAlign(node); setHAlign(halign); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 008e1d420..0704cc8a3 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -240,6 +240,7 @@ set(viewer_SOURCE_FILES llfloaternamedesc.cpp llfloaternotificationsconsole.cpp llfloaterobjectiminfo.cpp + llfloaterobjectweights.cpp llfloateropenobject.cpp llfloateroutbox.cpp llfloaterparcel.cpp @@ -762,6 +763,7 @@ set(viewer_HEADER_FILES llfloaternamedesc.h llfloaternotificationsconsole.h llfloaterobjectiminfo.h + llfloaterobjectweights.h llfloateropenobject.h llfloateroutbox.h llfloaterparcel.h diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp index d4a5108c5..01efd12e9 100644 --- a/indra/newview/llaccountingcostmanager.cpp +++ b/indra/newview/llaccountingcostmanager.cpp @@ -41,9 +41,15 @@ LLAccountingCostManager::LLAccountingCostManager() class LLAccountingCostResponder : public LLHTTPClient::ResponderWithResult { public: - LLAccountingCostResponder( const LLSD& objectIDs ) - : mObjectIDs( objectIDs ) + LLAccountingCostResponder( const LLSD& objectIDs, const LLHandle& observer_handle ) + : mObjectIDs( objectIDs ), + mObserverHandle( observer_handle ) { + LLAccountingCostObserver* observer = mObserverHandle.get(); + if (observer) + { + mTransactionID = observer->getTransactionID(); + } } void clearPendingRequests ( void ) @@ -54,19 +60,24 @@ public: } } - /*virtual*/ void error( U32 statusNum, const std::string& reason ) + void error( U32 statusNum, const std::string& reason ) { - llwarns << "Transport error "<getTransactionID() == mTransactionID) + { + observer->setErrorStatus(statusNum, reason); + } } - /*virtual*/ void result( const LLSD& content ) + void result( const LLSD& content ) { //Check for error if ( !content.isMap() || content.has("error") ) { llwarns << "Error on fetched data"<< llendl; - clearPendingRequests(); } else if (content.has("selected")) { @@ -74,15 +85,17 @@ public: F32 networkCost = 0.0f; F32 simulationCost = 0.0f; - //LLTransactionID transactionID; - - //transactionID = content["selected"][i]["local_id"].asUUID(); physicsCost = content["selected"]["physics"].asReal(); networkCost = content["selected"]["streaming"].asReal(); simulationCost = content["selected"]["simulation"].asReal(); SelectionCost selectionCost( /*transactionID,*/ physicsCost, networkCost, simulationCost ); - + + LLAccountingCostObserver* observer = mObserverHandle.get(); + if (observer && observer->getTransactionID() == mTransactionID) + { + observer->onWeightsUpdate(selectionCost); + } } clearPendingRequests(); @@ -94,10 +107,17 @@ public: private: //List of posted objects LLSD mObjectIDs; -}; + // Current request ID + LLUUID mTransactionID; + + // Cost update observer handle + LLHandle mObserverHandle; +}; //=============================================================================== -void LLAccountingCostManager::fetchCosts( eSelectionType selectionType, const std::string& url ) +void LLAccountingCostManager::fetchCosts( eSelectionType selectionType, + const std::string& url, + const LLHandle& observer_handle ) { // Invoking system must have already determined capability availability if ( !url.empty() ) @@ -144,7 +164,7 @@ void LLAccountingCostManager::fetchCosts( eSelectionType selectionType, const st LLSD dataToPost = LLSD::emptyMap(); dataToPost[keystr.c_str()] = objectList; - LLHTTPClient::post( url, dataToPost, new LLAccountingCostResponder( objectList )); + LLHTTPClient::post( url, dataToPost, new LLAccountingCostResponder( objectList, observer_handle )); } } else diff --git a/indra/newview/llaccountingcostmanager.h b/indra/newview/llaccountingcostmanager.h index 8ae696a98..731705288 100644 --- a/indra/newview/llaccountingcostmanager.h +++ b/indra/newview/llaccountingcostmanager.h @@ -27,8 +27,28 @@ #ifndef LL_ACCOUNTINGQUOTAMANAGER_H #define LL_ACCOUNTINGQUOTAMANAGER_H //=============================================================================== +#include "llhandle.h" + #include "llaccountingcost.h" //=============================================================================== +// An interface class for panels which display the parcel accounting information. +class LLAccountingCostObserver +{ +public: + LLAccountingCostObserver() { mObserverHandle.bind(this); } + virtual ~LLAccountingCostObserver() {} + virtual void onWeightsUpdate(const SelectionCost& selection_cost) = 0; + virtual void setErrorStatus(U32 status, const std::string& reason) = 0; + const LLHandle& getObserverHandle() const { return mObserverHandle; } + const LLUUID& getTransactionID() { return mTransactionID; } + +protected: + virtual void generateTransactionID() = 0; + + LLRootHandle mObserverHandle; + LLUUID mTransactionID; +}; +//=============================================================================== class LLAccountingCostManager : public LLSingleton { public: @@ -37,7 +57,8 @@ public: //Store an object that will be eventually fetched void addObject( const LLUUID& objectID ); //Request quotas for object list - void fetchCosts( eSelectionType selectionType, const std::string& url ); + void fetchCosts( eSelectionType selectionType, const std::string& url, + const LLHandle& observer_handle ); //Delete a specific object from the pending list void removePendingObject( const LLUUID& objectID ); diff --git a/indra/newview/llfloaterobjectweights.cpp b/indra/newview/llfloaterobjectweights.cpp new file mode 100644 index 000000000..f95d82f23 --- /dev/null +++ b/indra/newview/llfloaterobjectweights.cpp @@ -0,0 +1,276 @@ +/** + * @file llfloaterobjectweights.cpp + * @brief Object weights advanced view floater + * + * $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 "llviewerprecompiledheaders.h" + +#include "llfloaterobjectweights.h" + +#include "llparcel.h" + +#include "lltextbox.h" +#include "lluictrlfactory.h" + +#include "llagent.h" +#include "llfloatertools.h" // Singu Note: For placement beside the tools floater when it is opened. +#include "llviewerparcelmgr.h" +#include "llviewerregion.h" + +// virtual +bool LLCrossParcelFunctor::apply(LLViewerObject* obj) +{ + // Add the root object box. + mBoundingBox.addBBoxAgent(LLBBox(obj->getPositionRegion(), obj->getRotationRegion(), obj->getScale() * -0.5f, obj->getScale() * 0.5f).getAxisAligned()); + + // Extend the bounding box across all the children. + LLViewerObject::const_child_list_t children = obj->getChildren(); + for (LLViewerObject::const_child_list_t::const_iterator iter = children.begin(); + iter != children.end(); iter++) + { + LLViewerObject* child = *iter; + mBoundingBox.addBBoxAgent(LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned()); + } + + bool result = false; + + LLViewerRegion* region = obj->getRegion(); + if (region) + { + std::vector boxes; + boxes.push_back(mBoundingBox); + result = region->objectsCrossParcel(boxes); + } + + return result; +} + +LLFloaterObjectWeights::LLFloaterObjectWeights(const LLSD& key) +: LLFloater(key), + mSelectedObjects(NULL), + mSelectedPrims(NULL), + mSelectedDownloadWeight(NULL), + mSelectedPhysicsWeight(NULL), + mSelectedServerWeight(NULL), + mSelectedDisplayWeight(NULL), + mSelectedOnLand(NULL), + mRezzedOnLand(NULL), + mRemainingCapacity(NULL), + mTotalCapacity(NULL) +{ + //buildFromFile("floater_tools.xml"); + LLUICtrlFactory::getInstance()->buildFloater(this,"floater_object_weights.xml", NULL, false); +} + +LLFloaterObjectWeights::~LLFloaterObjectWeights() +{ +} + +// virtual +BOOL LLFloaterObjectWeights::postBuild() +{ + mSelectedObjects = getChild("objects"); + mSelectedPrims = getChild("prims"); + + mSelectedDownloadWeight = getChild("download"); + mSelectedPhysicsWeight = getChild("physics"); + mSelectedServerWeight = getChild("server"); + mSelectedDisplayWeight = getChild("display"); + + mSelectedOnLand = getChild("selected"); + mRezzedOnLand = getChild("rezzed_on_land"); + mRemainingCapacity = getChild("remaining_capacity"); + mTotalCapacity = getChild("total_capacity"); + + return TRUE; +} + +// virtual +void LLFloaterObjectWeights::onOpen() +{ + const LLRect& tools_rect = gFloaterTools->getRect(); + setOrigin(tools_rect.mRight, tools_rect.mTop - getRect().getHeight()); + refresh(); + updateLandImpacts(LLViewerParcelMgr::getInstance()->getFloatingParcelSelection()->getParcel()); +} + +// virtual +void LLFloaterObjectWeights::onWeightsUpdate(const SelectionCost& selection_cost) +{ + mSelectedDownloadWeight->setText(llformat("%.1f", selection_cost.mNetworkCost)); + mSelectedPhysicsWeight->setText(llformat("%.1f", selection_cost.mPhysicsCost)); + mSelectedServerWeight->setText(llformat("%.1f", selection_cost.mSimulationCost)); + + S32 render_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectRenderCost(); + mSelectedDisplayWeight->setText(llformat("%d", render_cost)); + + toggleWeightsLoadingIndicators(false); +} + +//virtual +void LLFloaterObjectWeights::setErrorStatus(U32 status, const std::string& reason) +{ + const std::string text = getString("nothing_selected"); + + mSelectedDownloadWeight->setText(text); + mSelectedPhysicsWeight->setText(text); + mSelectedServerWeight->setText(text); + mSelectedDisplayWeight->setText(text); + + toggleWeightsLoadingIndicators(false); +} + +void LLFloaterObjectWeights::updateLandImpacts(const LLParcel* parcel) +{ + if (!parcel || LLSelectMgr::getInstance()->getSelection()->isEmpty()) + { + updateIfNothingSelected(); + } + else + { + S32 rezzed_prims = parcel->getSimWidePrimCount(); + S32 total_capacity = parcel->getSimWideMaxPrimCapacity(); + + mRezzedOnLand->setText(llformat("%d", rezzed_prims)); + mRemainingCapacity->setText(llformat("%d", total_capacity - rezzed_prims)); + mTotalCapacity->setText(llformat("%d", total_capacity)); + + toggleLandImpactsLoadingIndicators(false); + } +} + +void LLFloaterObjectWeights::refresh() +{ + LLSelectMgr* sel_mgr = LLSelectMgr::getInstance(); + + if (sel_mgr->getSelection()->isEmpty()) + { + updateIfNothingSelected(); + } + else + { + S32 prim_count = sel_mgr->getSelection()->getObjectCount(); + S32 link_count = sel_mgr->getSelection()->getRootObjectCount(); + F32 prim_equiv = sel_mgr->getSelection()->getSelectedLinksetCost(); + + mSelectedObjects->setText(llformat("%d", link_count)); + mSelectedPrims->setText(llformat("%d", prim_count)); + mSelectedOnLand->setText(llformat("%.1d", (S32)prim_equiv)); + + LLCrossParcelFunctor func; + if (sel_mgr->getSelection()->applyToRootObjects(&func, true)) + { + // Some of the selected objects cross parcel bounds. + // We don't display object weights and land impacts in this case. + const std::string text = getString("nothing_selected"); + + mRezzedOnLand->setText(text); + mRemainingCapacity->setText(text); + mTotalCapacity->setText(text); + + toggleLandImpactsLoadingIndicators(false); + } + + LLViewerRegion* region = gAgent.getRegion(); + if (region && region->capabilitiesReceived()) + { + for (LLObjectSelection::valid_root_iterator iter = sel_mgr->getSelection()->valid_root_begin(); + iter != sel_mgr->getSelection()->valid_root_end(); ++iter) + { + LLAccountingCostManager::getInstance()->addObject((*iter)->getObject()->getID()); + } + + std::string url = region->getCapability("ResourceCostSelected"); + if (!url.empty()) + { + // Update the transaction id before the new fetch request + generateTransactionID(); + + LLAccountingCostManager::getInstance()->fetchCosts(Roots, url, getObserverHandle()); + toggleWeightsLoadingIndicators(true); + } + } + else + { + //LL_WARNS() << "Failed to get region capabilities" << LL_ENDL; + llwarns << "Failed to get region capabilities" << llendl; + } + } +} + +// virtual +void LLFloaterObjectWeights::generateTransactionID() +{ + mTransactionID.generate(); +} + +void LLFloaterObjectWeights::toggleWeightsLoadingIndicators(bool visible) +{ + /* Singu TODO: LLLoadingIndicator + childSetVisible("download_loading_indicator", visible); + childSetVisible("physics_loading_indicator", visible); + childSetVisible("server_loading_indicator", visible); + childSetVisible("display_loading_indicator", visible); + */ + + mSelectedDownloadWeight->setVisible(!visible); + mSelectedPhysicsWeight->setVisible(!visible); + mSelectedServerWeight->setVisible(!visible); + mSelectedDisplayWeight->setVisible(!visible); +} + +void LLFloaterObjectWeights::toggleLandImpactsLoadingIndicators(bool visible) +{ + /* Singu TODO: LLLoadingIndicator + childSetVisible("selected_loading_indicator", visible); + childSetVisible("rezzed_on_land_loading_indicator", visible); + childSetVisible("remaining_capacity_loading_indicator", visible); + childSetVisible("total_capacity_loading_indicator", visible); + */ + + mSelectedOnLand->setVisible(!visible); + mRezzedOnLand->setVisible(!visible); + mRemainingCapacity->setVisible(!visible); + mTotalCapacity->setVisible(!visible); +} + +void LLFloaterObjectWeights::updateIfNothingSelected() +{ + const std::string text = getString("nothing_selected"); + + mSelectedObjects->setText(text); + mSelectedPrims->setText(text); + + mSelectedDownloadWeight->setText(text); + mSelectedPhysicsWeight->setText(text); + mSelectedServerWeight->setText(text); + mSelectedDisplayWeight->setText(text); + + mSelectedOnLand->setText(text); + mRezzedOnLand->setText(text); + mRemainingCapacity->setText(text); + mTotalCapacity->setText(text); + + toggleWeightsLoadingIndicators(false); + toggleLandImpactsLoadingIndicators(false); +} diff --git a/indra/newview/llfloaterobjectweights.h b/indra/newview/llfloaterobjectweights.h new file mode 100644 index 000000000..018627824 --- /dev/null +++ b/indra/newview/llfloaterobjectweights.h @@ -0,0 +1,94 @@ +/** + * @file llfloaterobjectweights.h + * @brief Object weights advanced view floater + * + * $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_LLFLOATEROBJECTWEIGHTS_H +#define LL_LLFLOATEROBJECTWEIGHTS_H + +#include "llfloater.h" + +#include "llaccountingcostmanager.h" +#include "llselectmgr.h" + +class LLParcel; +class LLTextBox; + +/** + * struct LLCrossParcelFunctor + * + * A functor that checks whether a bounding box for all + * selected objects crosses a region or parcel bounds. + */ +struct LLCrossParcelFunctor : public LLSelectedObjectFunctor +{ + /*virtual*/ bool apply(LLViewerObject* obj); + +private: + LLBBox mBoundingBox; +}; + + +class LLFloaterObjectWeights : public LLFloater, LLAccountingCostObserver +, public LLFloaterSingleton +{ +public: + LOG_CLASS(LLFloaterObjectWeights); + + LLFloaterObjectWeights(const LLSD& key); + ~LLFloaterObjectWeights(); + + /*virtual*/ BOOL postBuild(); + + /*virtual*/ void onOpen(); + + /*virtual*/ void onWeightsUpdate(const SelectionCost& selection_cost); + /*virtual*/ void setErrorStatus(U32 status, const std::string& reason); + + void updateLandImpacts(const LLParcel* parcel); + void refresh(); + +private: + /*virtual*/ void generateTransactionID(); + + void toggleWeightsLoadingIndicators(bool visible); + void toggleLandImpactsLoadingIndicators(bool visible); + + void updateIfNothingSelected(); + + LLTextBox *mSelectedObjects; + LLTextBox *mSelectedPrims; + + LLTextBox *mSelectedDownloadWeight; + LLTextBox *mSelectedPhysicsWeight; + LLTextBox *mSelectedServerWeight; + LLTextBox *mSelectedDisplayWeight; + + LLTextBox *mSelectedOnLand; + LLTextBox *mRezzedOnLand; + LLTextBox *mRemainingCapacity; + LLTextBox *mTotalCapacity; +}; + +#endif //LL_LLFLOATEROBJECTWEIGHTS_H diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index a690b42e5..d26944595 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -47,6 +47,7 @@ #include "llfloaterbuildoptions.h" #include "llfloatermediasettings.h" #include "llfloateropenobject.h" +#include "llfloaterobjectweights.h" #include "llfocusmgr.h" #include "llmediaentry.h" #include "llmediactrl.h" @@ -99,7 +100,6 @@ // Globals LLFloaterTools *gFloaterTools = NULL; - const std::string PANEL_NAMES[LLFloaterTools::PANEL_COUNT] = { std::string("General"), // PANEL_GENERAL, @@ -124,10 +124,27 @@ void commit_radio_group_focus(LLUICtrl* ctrl); void commit_radio_group_move(LLUICtrl* ctrl); void commit_radio_group_edit(LLUICtrl* ctrl); void commit_radio_group_land(LLUICtrl* ctrl); - void commit_slider_zoom(LLUICtrl *ctrl); void commit_select_tool(LLUICtrl *ctrl, void *data); +/** + * Class LLLandImpactsObserver + * + * An observer class to monitor parcel selection and update + * the land impacts data from a parcel containing the selected object. + */ +class LLLandImpactsObserver : public LLParcelObserver +{ +public: + virtual void changed() + { + LLFloaterTools* tools_floater = gFloaterTools; + if(tools_floater) + { + tools_floater->updateLandImpacts(); + } + } +}; //static void* LLFloaterTools::createPanelPermissions(void* data) @@ -249,13 +266,13 @@ BOOL LLFloaterTools::postBuild() mRadioStretch = getChild("radio stretch"); mRadioSelectFace = getChild("radio select face"); mRadioAlign = getChild("radio align"); + mBtnGridOptions = getChild("Options..."); mTitleMedia = getChild("title_media"); mCheckSelectIndividual = getChild("checkbox edit linked parts"); getChild("checkbox edit linked parts")->setValue((BOOL)gSavedSettings.getBOOL("EditLinkedParts")); mCheckSnapToGrid = getChild("checkbox snap to grid"); getChild("checkbox snap to grid")->setValue((BOOL)gSavedSettings.getBOOL("SnapEnabled")); - mBtnGridOptions = getChild("Options..."); mCheckStretchUniform = getChild("checkbox uniform"); getChild("checkbox uniform")->setValue((BOOL)gSavedSettings.getBOOL("ScaleUniform")); mCheckStretchTexture = getChild("checkbox stretch textures"); @@ -267,6 +284,7 @@ BOOL LLFloaterTools::postBuild() mCheckShowHighlight = getChild("checkbox show highlight"); mCheckActualRoot = getChild("checkbox actual root"); + // // Create Buttons // @@ -283,7 +301,7 @@ BOOL LLFloaterTools::postBuild() } } if ((mComboTreesGrass = findChild("trees_grass"))) - childSetCommitCallback("trees_grass", onSelectTreesGrass, (void*)0); + mComboTreesGrass->setCommitCallback(boost::bind(&LLFloaterTools::onSelectTreesGrass, this)); mCheckCopySelection = getChild("checkbox copy selection"); getChild("checkbox copy selection")->setValue((BOOL)gSavedSettings.getBOOL("CreateToolCopySelection")); mCheckSticky = getChild("checkbox sticky"); @@ -303,7 +321,6 @@ BOOL LLFloaterTools::postBuild() mSliderDozerSize = getChild("slider brush size"); getChild("slider brush size")->setValue(gSavedSettings.getF32("LandBrushSize")); - mSliderDozerForce = getChild("slider force"); // the setting stores the actual force multiplier, but the slider is logarithmic, so we convert here getChild("slider force")->setValue(log10(gSavedSettings.getF32("LandBrushForce"))); @@ -404,6 +421,8 @@ LLFloaterTools::LLFloaterTools() mPanelFace(NULL), mPanelLandInfo(NULL), + mLandImpactsObserver(NULL), + mDirty(TRUE), mNeedMediaTitle(TRUE) { @@ -434,12 +453,24 @@ LLFloaterTools::LLFloaterTools() mCommitCallbackRegistrar.add("BuildTool.DeleteMedia", boost::bind(&LLFloaterTools::onClickBtnDeleteMedia,this)); mCommitCallbackRegistrar.add("BuildTool.EditMedia", boost::bind(&LLFloaterTools::onClickBtnEditMedia,this)); + mLandImpactsObserver = new LLLandImpactsObserver(); + LLViewerParcelMgr::getInstance()->addObserver(mLandImpactsObserver); + LLUICtrlFactory::getInstance()->buildFloater(this,"floater_tools.xml",&factory_map,FALSE); + if (LLTextBox* text = findChild("selection_count")) + { + text->setClickedCallback(boost::bind(LLFloaterObjectWeights::toggleInstance, LLSD())); + text->setColor(gSavedSettings.getColor4("HTMLLinkColor")); + } } LLFloaterTools::~LLFloaterTools() { // children automatically deleted + gFloaterTools = NULL; + + LLViewerParcelMgr::getInstance()->removeObserver(mLandImpactsObserver); + delete mLandImpactsObserver; } void LLFloaterTools::setStatusText(const std::string& text) @@ -480,62 +511,114 @@ void LLFloaterTools::refresh() // Refresh object and prim count labels LLLocale locale(LLLocale::USER_LOCALE); - // Added in Link Num value -HgB - S32 object_count = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount(); - S32 prim_count = LLSelectMgr::getInstance()->getEditSelection()->getObjectCount(); - std::string value_string; - std::string desc_string; - if ((gSavedSettings.getBOOL("EditLinkedParts"))&&(prim_count == 1)) //Selecting a single prim in "Edit Linked" mode, show link number +#if 0 + if (!gMeshRepo.meshRezEnabled()) { - desc_string = "Link number:"; + std::string obj_count_string; + LLResMgr::getInstance()->getIntegerString(obj_count_string, LLSelectMgr::getInstance()->getSelection()->getRootObjectCount()); + getChild("selection_count")->setTextArg("[OBJ_COUNT]", obj_count_string); + std::string prim_count_string; + LLResMgr::getInstance()->getIntegerString(prim_count_string, LLSelectMgr::getInstance()->getSelection()->getObjectCount()); + getChild("selection_count")->setTextArg("[PRIM_COUNT]", prim_count_string); - LLViewerObject* selected = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); - if (selected && selected->getRootEdit()) + // calculate selection rendering cost + if (sShowObjectCost) { - LLViewerObject::child_list_t children = selected->getRootEdit()->getChildren(); - if (children.empty()) + std::string prim_cost_string; + S32 render_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectRenderCost(); + LLResMgr::getInstance()->getIntegerString(prim_cost_string, render_cost); + getChild("RenderingCost")->setTextArg("[COUNT]", prim_cost_string); + } + + // disable the object and prim counts if nothing selected + bool have_selection = ! LLSelectMgr::getInstance()->getSelection()->isEmpty(); + getChildView("obj_count")->setEnabled(have_selection); + getChildView("prim_count")->setEnabled(have_selection); + getChildView("RenderingCost")->setEnabled(have_selection && sShowObjectCost); + } + else +#endif + { + F32 link_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedLinksetCost(); + S32 link_count = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount(); + + // Added in Link Num value -HgB + S32 prim_count = LLSelectMgr::getInstance()->getEditSelection()->getObjectCount(); + std::string value_string; + if ((prim_count == 1) && gSavedSettings.getBOOL("EditLinkedParts")) //Selecting a single prim in "Edit Linked" mode, show link number + { + childSetTextArg("link_num_obj_count", "[DESC]", std::string("Link number:")); + + LLViewerObject* selected = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + if (selected && selected->getRootEdit()) { - value_string = "0"; // An unlinked prim is "link 0". - } - else - { - children.push_front(selected->getRootEdit()); // need root in the list too - S32 index = 0; - for (LLViewerObject::child_list_t::iterator iter = children.begin(); iter != children.end(); ++iter) + LLViewerObject::child_list_t children = selected->getRootEdit()->getChildren(); + if (children.empty()) { - index++; - if ((*iter)->isSelected()) + value_string = "0"; // An unlinked prim is "link 0". + } + else + { + children.push_front(selected->getRootEdit()); // need root in the list too + S32 index = 0; + for (LLViewerObject::child_list_t::iterator iter = children.begin(); iter != children.end(); ++iter, ++index) { - LLResMgr::getInstance()->getIntegerString(value_string, index); - break; + if ((*iter)->isSelected()) + { + LLResMgr::getInstance()->getIntegerString(value_string, index); + break; + } } } } } - } - else - { - desc_string = "Selected objects:"; - LLResMgr::getInstance()->getIntegerString(value_string, object_count); - } - childSetTextArg("link_num_obj_count", "[DESC]", desc_string); - childSetTextArg("link_num_obj_count", "[NUM]", value_string); + else + { + childSetTextArg("link_num_obj_count", "[DESC]", std::string("Selected objects:")); + LLResMgr::getInstance()->getIntegerString(value_string, link_count); + } + childSetTextArg("link_num_obj_count", "[NUM]", value_string); - LLStringUtil::format_map_t selection_args; - selection_args["COUNT"] = llformat("%.1d", (S32)prim_count); - if(gMeshRepo.meshRezEnabled()) - { - F32 link_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectCost(); - LLStringUtil::format_map_t prim_equiv_args; - prim_equiv_args["SEL_WEIGHT"] = llformat("%.0f", link_cost); - selection_args["PE_STRING"] = getString("status_selectprimequiv", prim_equiv_args); + /* Singu Note: We're not using this yet because we have no place to put it + LLCrossParcelFunctor func; + if (LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, true)) + { + // Selection crosses parcel bounds. + // We don't display remaining land capacity in this case. + const LLStringExplicit empty_str(""); + childSetTextArg("remaining_capacity", "[CAPACITY_STRING]", empty_str); + } + else + */ + { + LLViewerObject* selected_object = mObjectSelection->getFirstObject(); + if (selected_object) + { + // Select a parcel at the currently selected object's position. + LLViewerParcelMgr::getInstance()->selectParcelAt(selected_object->getPositionGlobal()); + } + else + { + //LL_WARNS() << "Failed to get selected object" << LL_ENDL; + } + } + + LLStringUtil::format_map_t selection_args; + selection_args["OBJ_COUNT"] = llformat("%.1d", prim_count); + selection_args["LAND_IMPACT"] = llformat("%.1d", (S32)link_cost); + + std::ostringstream selection_info; + + selection_info << getString("status_selectcount", selection_args); + + getChild("selection_count")->setText(selection_info.str()); + + bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty(); + childSetVisible("selection_count", have_selection); + //childSetVisible("remaining_capacity", have_selection); + childSetVisible("selection_empty", !have_selection); } - else - { - selection_args["PE_STRING"] = ""; - } - std::string prim_count_string = getString("status_selectcount",selection_args); - childSetText("prim_count", prim_count_string); + // Refresh child tabs mPanelPermissions->refresh(); @@ -546,6 +629,12 @@ void LLFloaterTools::refresh() refreshMedia(); mPanelContents->refresh(); mPanelLandInfo->refresh(); + + // Refresh the advanced weights floater + if (LLFloaterObjectWeights::instanceVisible()) + { + LLFloaterObjectWeights::getInstance()->refresh(); + } } void LLFloaterTools::draw() @@ -606,8 +695,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) mRadioZoom ->setVisible( focus_visible ); mRadioOrbit ->setVisible( focus_visible ); mRadioPan ->setVisible( focus_visible ); - childSetVisible("slider zoom", focus_visible); - childSetEnabled("slider zoom", gCameraBtnZoom); + getChildView("slider zoom")->setVisible(focus_visible); + getChildView("slider zoom")->setEnabled(gCameraBtnZoom); mRadioZoom ->set(!gCameraBtnOrbit && !gCameraBtnPan && @@ -625,7 +714,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) (mask == (MASK_PAN | MASK_ALT)) ); // multiply by correction factor because volume sliders go [0, 0.5] - childSetValue( "slider zoom", gAgentCamera.getCameraZoomFraction() * 0.5f); + getChild("slider zoom")->setValue(gAgentCamera.getCameraZoomFraction() * 0.5f); // Move buttons BOOL move_visible = (tool == LLToolGrab::getInstance()); @@ -699,7 +788,6 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) case SELECT_TYPE_HUD: mComboGridMode->add(getString("grid_screen_text")); mComboGridMode->add(getString("grid_local_text")); - //mComboGridMode->add(getString("grid_reference_text")); break; case SELECT_TYPE_WORLD: mComboGridMode->add(getString("grid_world_text")); @@ -772,10 +860,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) if (mBtnLand) mBtnLand ->setToggleState( land_visible ); - // mRadioEditLand ->set( tool == LLToolBrushLand::getInstance() ); if (mRadioSelectLand) mRadioSelectLand->set( tool == LLToolSelectLand::getInstance() ); - // mRadioEditLand ->setVisible( land_visible ); if (mRadioSelectLand) mRadioSelectLand->setVisible( land_visible ); S32 dozer_mode = gSavedSettings.getS32("RadioLandBrushAction"); @@ -810,6 +896,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) mRadioDozerRevert ->set( tool == LLToolBrushLand::getInstance() && dozer_mode == 5); mRadioDozerRevert ->setVisible( land_visible ); } + if (mBtnApplyToSelection) { mBtnApplyToSelection->setVisible( land_visible ); @@ -826,9 +913,14 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) mSliderDozerForce ->setVisible( land_visible ); getChildView("Strength:")->setVisible( land_visible); } - - childSetVisible("link_num_obj_count", !land_visible); - childSetVisible("prim_count", !land_visible); + + bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty(); + + getChildView("link_num_obj_count")->setVisible(!land_visible && have_selection); + getChildView("selection_count")->setVisible(!land_visible && have_selection); + //getChildView("remaining_capacity")->setVisible(!land_visible && have_selection); + getChildView("selection_empty")->setVisible(!land_visible && !have_selection); + static const LLCachedControl mini("LiruMiniBuildFloater"); mTab->setVisible(!mini && !land_visible); getChildView("mini_button")->setVisible(!land_visible); @@ -909,9 +1001,12 @@ void LLFloaterTools::onClose(bool app_quitting) // gMenuBarView->setItemVisible(std::string("Tools"), FALSE); // gMenuBarView->arrange(); - + if(LLFloaterMediaSettings::instanceExists()) LLFloaterMediaSettings::getInstance()->close(); + + // hide the advanced object weights floater + LLFloaterObjectWeights::hideInstance(); } void LLFloaterTools::showPanel(EInfoPanel panel) @@ -922,7 +1017,6 @@ void LLFloaterTools::showPanel(EInfoPanel panel) void click_popup_info(void*) { -// gBuildView->setPropertiesPanelOpen(TRUE); } void click_popup_done(void*) @@ -1094,7 +1188,6 @@ void commit_grid_mode(LLUICtrl *ctrl) void LLFloaterTools::onClickGridOptions() { - //LLFloaterTools* floaterp = (LLFloaterTools*)data; LLFloaterBuildOptions::show(NULL); // RN: this makes grid options dependent on build tools window //floaterp->addDependentFloater(LLFloaterBuildOptions::getInstance(), FALSE); @@ -1176,6 +1269,39 @@ bool LLFloaterTools::selectedMediaEditable() return selected_Media_editable; } + +void LLFloaterTools::updateLandImpacts() +{ + LLParcel *parcel = mParcelSelection->getParcel(); + if (!parcel) + { + return; + } + + /* Singu Note: We're not using this yet because we have no place to put it + S32 rezzed_prims = parcel->getSimWidePrimCount(); + S32 total_capacity = parcel->getSimWideMaxPrimCapacity(); + + std::string remaining_capacity_str = ""; + + bool show_mesh_cost = gMeshRepo.meshRezEnabled(); + if (show_mesh_cost) + { + LLStringUtil::format_map_t remaining_capacity_args; + remaining_capacity_args["LAND_CAPACITY"] = llformat("%d", total_capacity - rezzed_prims); + remaining_capacity_str = getString("status_remaining_capacity", remaining_capacity_args); + } + + childSetTextArg("remaining_capacity", "[CAPACITY_STRING]", remaining_capacity_str); + */ + + // Update land impacts info in the weights floater + if (LLFloaterObjectWeights::instanceVisible()) + { + LLFloaterObjectWeights::getInstance()->updateLandImpacts(parcel); + } +} + void LLFloaterTools::getMediaState() { LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection(); @@ -1962,10 +2088,9 @@ void LLFloaterTools::updateMediaSettings() mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; } -// static -void LLFloaterTools::onSelectTreesGrass(LLUICtrl*, void*) +void LLFloaterTools::onSelectTreesGrass() { - const std::string &selected = gFloaterTools->mComboTreesGrass->getValue(); + const std::string& selected = mComboTreesGrass->getValue(); LLPCode pcode = LLToolPlacer::getObjectType(); if (pcode == LL_PCODE_LEGACY_TREE) { diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index 3a6d2cbfb..73c13f558 100644 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -53,6 +53,7 @@ class LLMediaCtrl; class LLTool; class LLParcelSelection; class LLObjectSelection; +class LLLandImpactsObserver; typedef LLSafeHandle LLObjectSelectionHandle; @@ -110,6 +111,7 @@ public: void updateMediaTitle(); void navigateToTitleMedia( const std::string url ); bool selectedMediaEditable(); + void updateLandImpacts(); LLPanelFace* getPanelFace() { return mPanelFace; } @@ -178,7 +180,6 @@ public: LLCheckBoxCtrl *mCheckCopyRotates; // Land buttons -// LLCheckBoxCtrl *mRadioEditLand; LLCheckBoxCtrl *mRadioSelectLand; LLCheckBoxCtrl *mRadioDozerFlatten; @@ -202,18 +203,21 @@ public: LLPanelFace *mPanelFace; LLPanelLandInfo *mPanelLandInfo; + LLLandImpactsObserver* mLandImpactsObserver; + LLParcelSelectionHandle mParcelSelection; LLObjectSelectionHandle mObjectSelection; LLMediaCtrl *mTitleMedia; bool mNeedMediaTitle; + private: BOOL mDirty; std::map mStatusText; + void onSelectTreesGrass(); void updateTreeGrassCombo(bool visible); - static void onSelectTreesGrass(LLUICtrl*, void*); protected: LLSD mMediaSettings; }; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 7103a7ede..4ba3da375 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1737,7 +1737,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("RemoteParcelRequest"); capabilityNames.append("RenderMaterials"); capabilityNames.append("RequestTextureDownload"); - //capabilityNames.append("ResourceCostSelected"); //Object weights (llfloaterobjectweights.cpp) + capabilityNames.append("ResourceCostSelected"); capabilityNames.append("RetrieveNavMeshSrc"); capabilityNames.append("SearchStatRequest"); capabilityNames.append("SearchStatTracking"); diff --git a/indra/newview/skins/default/xui/de/floater_object_weights.xml b/indra/newview/skins/default/xui/de/floater_object_weights.xml new file mode 100644 index 000000000..4bceb534e --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_object_weights.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/de/floater_tools.xml b/indra/newview/skins/default/xui/de/floater_tools.xml index b37289265..c879137cd 100644 --- a/indra/newview/skins/default/xui/de/floater_tools.xml +++ b/indra/newview/skins/default/xui/de/floater_tools.xml @@ -452,6 +452,5 @@ Welt Referenz Anhänge - , Kosten: [SEL_WEIGHT] - Prims: [COUNT][PE_STRING] + Prims: [OBJ_COUNT], Kosten: [LAND_IMPACT] diff --git a/indra/newview/skins/default/xui/en-us/floater_object_weights.xml b/indra/newview/skins/default/xui/en-us/floater_object_weights.xml new file mode 100644 index 000000000..1c6581c63 --- /dev/null +++ b/indra/newview/skins/default/xui/en-us/floater_object_weights.xml @@ -0,0 +1,326 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en-us/floater_tools.xml b/indra/newview/skins/default/xui/en-us/floater_tools.xml index 09bb81cb4..4afe0d4a9 100644 --- a/indra/newview/skins/default/xui/en-us/floater_tools.xml +++ b/indra/newview/skins/default/xui/en-us/floater_tools.xml @@ -5,6 +5,13 @@ name="toolbox floater" rect_control="ToolboxRect" sound_flags="0" title="" short_title="Build" width="272"> + + Primitives: [OBJ_COUNT], LI: [LAND_IMPACT] + + + Remaining capacity [LAND_CAPACITY]. +