807 lines
27 KiB
C++
807 lines
27 KiB
C++
/**
|
|
* @file llfloaterpathfindinglinksets.cpp
|
|
* @brief "Pathfinding linksets" floater, allowing manipulation of the linksets on the current region.
|
|
* @author Stinson@lindenlab.com
|
|
*
|
|
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
|
* Second Life Viewer Source Code
|
|
* Copyright (C) 2012, 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 "llfloaterpathfindinglinksets.h"
|
|
|
|
#include <string>
|
|
|
|
#include <boost/bind.hpp>
|
|
|
|
#include "llagent.h"
|
|
#include "llbutton.h"
|
|
#include "llcombobox.h"
|
|
#include "llfloaterpathfindingobjects.h"
|
|
#include "lllineeditor.h"
|
|
#include "llnotificationsutil.h"
|
|
#include "llpathfindinglinkset.h"
|
|
#include "llpathfindinglinksetlist.h"
|
|
#include "llpathfindingmanager.h"
|
|
#include "llscrolllistitem.h"
|
|
#include "llsd.h"
|
|
#include "lltextbox.h"
|
|
#include "llui.h"
|
|
#include "lluictrlfactory.h"
|
|
#include "lluictrl.h"
|
|
#include "v3math.h"
|
|
#include "v4color.h"
|
|
|
|
#define XUI_LINKSET_USE_NONE 0
|
|
#define XUI_LINKSET_USE_WALKABLE 1
|
|
#define XUI_LINKSET_USE_STATIC_OBSTACLE 2
|
|
#define XUI_LINKSET_USE_DYNAMIC_OBSTACLE 3
|
|
#define XUI_LINKSET_USE_MATERIAL_VOLUME 4
|
|
#define XUI_LINKSET_USE_EXCLUSION_VOLUME 5
|
|
#define XUI_LINKSET_USE_DYNAMIC_PHANTOM 6
|
|
|
|
//---------------------------------------------------------------------------
|
|
// LLFloaterPathfindingLinksets
|
|
//---------------------------------------------------------------------------
|
|
|
|
void LLFloaterPathfindingLinksets::openLinksetsWithSelectedObjects()
|
|
{
|
|
LLFloaterPathfindingLinksets* linksetsFloater = getInstance();
|
|
linksetsFloater->clearFilters();
|
|
linksetsFloater->showFloaterWithSelectionObjects();
|
|
}
|
|
|
|
LLFloaterPathfindingLinksets::LLFloaterPathfindingLinksets(const LLSD& pSeed)
|
|
: LLFloaterPathfindingObjects(/*pSeed*/),
|
|
mFilterByName(NULL),
|
|
mFilterByDescription(NULL),
|
|
mFilterByLinksetUse(NULL),
|
|
mEditLinksetUse(NULL),
|
|
mEditLinksetUseWalkable(NULL),
|
|
mEditLinksetUseStaticObstacle(NULL),
|
|
mEditLinksetUseDynamicObstacle(NULL),
|
|
mEditLinksetUseMaterialVolume(NULL),
|
|
mEditLinksetUseExclusionVolume(NULL),
|
|
mEditLinksetUseDynamicPhantom(NULL),
|
|
mLabelWalkabilityCoefficients(NULL),
|
|
mLabelEditA(NULL),
|
|
mLabelSuggestedUseA(NULL),
|
|
mEditA(NULL),
|
|
mLabelEditB(NULL),
|
|
mLabelSuggestedUseB(NULL),
|
|
mEditB(NULL),
|
|
mLabelEditC(NULL),
|
|
mLabelSuggestedUseC(NULL),
|
|
mEditC(NULL),
|
|
mLabelEditD(NULL),
|
|
mLabelSuggestedUseD(NULL),
|
|
mEditD(NULL),
|
|
mApplyEditsButton(NULL),
|
|
mBeaconColor(),
|
|
mPreviousValueA(LLPathfindingLinkset::MAX_WALKABILITY_VALUE),
|
|
mPreviousValueB(LLPathfindingLinkset::MAX_WALKABILITY_VALUE),
|
|
mPreviousValueC(LLPathfindingLinkset::MAX_WALKABILITY_VALUE),
|
|
mPreviousValueD(LLPathfindingLinkset::MAX_WALKABILITY_VALUE)
|
|
{
|
|
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_pathfinding_linksets.xml");
|
|
}
|
|
|
|
LLFloaterPathfindingLinksets::~LLFloaterPathfindingLinksets()
|
|
{
|
|
}
|
|
|
|
BOOL LLFloaterPathfindingLinksets::postBuild()
|
|
{
|
|
mBeaconColor = LLUI::sColorsGroup->getColor("PathfindingLinksetBeaconColor");
|
|
|
|
mFilterByName = findChild<LLLineEditor>("filter_by_name");
|
|
llassert(mFilterByName != NULL);
|
|
mFilterByName->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
|
|
mFilterByName->setSelectAllonFocusReceived(true);
|
|
mFilterByName->setCommitOnFocusLost(true);
|
|
|
|
mFilterByDescription = findChild<LLLineEditor>("filter_by_description");
|
|
llassert(mFilterByDescription != NULL);
|
|
mFilterByDescription->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
|
|
mFilterByDescription->setSelectAllonFocusReceived(true);
|
|
mFilterByDescription->setCommitOnFocusLost(true);
|
|
|
|
mFilterByLinksetUse = findChild<LLComboBox>("filter_by_linkset_use");
|
|
llassert(mFilterByLinksetUse != NULL);
|
|
mFilterByLinksetUse->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
|
|
|
|
childSetAction("apply_filters", boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
|
|
childSetAction("clear_filters", boost::bind(&LLFloaterPathfindingLinksets::onClearFiltersClicked, this));
|
|
|
|
mEditLinksetUse = findChild<LLComboBox>("edit_linkset_use");
|
|
llassert(mEditLinksetUse != NULL);
|
|
mEditLinksetUse->clearRows();
|
|
|
|
mEditLinksetUseUnset = mEditLinksetUse->add(getString("linkset_choose_use"), XUI_LINKSET_USE_NONE);
|
|
llassert(mEditLinksetUseUnset != NULL);
|
|
|
|
mEditLinksetUseWalkable = mEditLinksetUse->add(getLinksetUseString(LLPathfindingLinkset::kWalkable), XUI_LINKSET_USE_WALKABLE);
|
|
llassert(mEditLinksetUseWalkable != NULL);
|
|
|
|
mEditLinksetUseStaticObstacle = mEditLinksetUse->add(getLinksetUseString(LLPathfindingLinkset::kStaticObstacle), XUI_LINKSET_USE_STATIC_OBSTACLE);
|
|
llassert(mEditLinksetUseStaticObstacle != NULL);
|
|
|
|
mEditLinksetUseDynamicObstacle = mEditLinksetUse->add(getLinksetUseString(LLPathfindingLinkset::kDynamicObstacle), XUI_LINKSET_USE_DYNAMIC_OBSTACLE);
|
|
llassert(mEditLinksetUseDynamicObstacle != NULL);
|
|
|
|
mEditLinksetUseMaterialVolume = mEditLinksetUse->add(getLinksetUseString(LLPathfindingLinkset::kMaterialVolume), XUI_LINKSET_USE_MATERIAL_VOLUME);
|
|
llassert(mEditLinksetUseMaterialVolume != NULL);
|
|
|
|
mEditLinksetUseExclusionVolume = mEditLinksetUse->add(getLinksetUseString(LLPathfindingLinkset::kExclusionVolume), XUI_LINKSET_USE_EXCLUSION_VOLUME);
|
|
llassert(mEditLinksetUseExclusionVolume != NULL);
|
|
|
|
mEditLinksetUseDynamicPhantom = mEditLinksetUse->add(getLinksetUseString(LLPathfindingLinkset::kDynamicPhantom), XUI_LINKSET_USE_DYNAMIC_PHANTOM);
|
|
llassert(mEditLinksetUseDynamicPhantom != NULL);
|
|
|
|
mEditLinksetUse->selectFirstItem();
|
|
|
|
mLabelWalkabilityCoefficients = findChild<LLTextBox>("walkability_coefficients_label");
|
|
llassert(mLabelWalkabilityCoefficients != NULL);
|
|
|
|
mLabelEditA = findChild<LLTextBox>("edit_a_label");
|
|
llassert(mLabelEditA != NULL);
|
|
|
|
mLabelSuggestedUseA = findChild<LLTextBox>("suggested_use_a_label");
|
|
llassert(mLabelSuggestedUseA != NULL);
|
|
|
|
mEditA = findChild<LLLineEditor>("edit_a_value");
|
|
llassert(mEditA != NULL);
|
|
mEditA->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32);
|
|
mEditA->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueA));
|
|
|
|
mLabelEditB = findChild<LLTextBox>("edit_b_label");
|
|
llassert(mLabelEditB != NULL);
|
|
|
|
mLabelSuggestedUseB = findChild<LLTextBox>("suggested_use_b_label");
|
|
llassert(mLabelSuggestedUseB != NULL);
|
|
|
|
mEditB = findChild<LLLineEditor>("edit_b_value");
|
|
llassert(mEditB != NULL);
|
|
mEditB->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32);
|
|
mEditB->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueB));
|
|
|
|
mLabelEditC = findChild<LLTextBox>("edit_c_label");
|
|
llassert(mLabelEditC != NULL);
|
|
|
|
mLabelSuggestedUseC = findChild<LLTextBox>("suggested_use_c_label");
|
|
llassert(mLabelSuggestedUseC != NULL);
|
|
|
|
mEditC = findChild<LLLineEditor>("edit_c_value");
|
|
llassert(mEditC != NULL);
|
|
mEditC->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32);
|
|
mEditC->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueC));
|
|
|
|
mLabelEditD = findChild<LLTextBox>("edit_d_label");
|
|
llassert(mLabelEditD != NULL);
|
|
|
|
mLabelSuggestedUseD = findChild<LLTextBox>("suggested_use_d_label");
|
|
llassert(mLabelSuggestedUseD != NULL);
|
|
|
|
mEditD = findChild<LLLineEditor>("edit_d_value");
|
|
llassert(mEditD != NULL);
|
|
mEditD->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32);
|
|
mEditD->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueD));
|
|
|
|
mApplyEditsButton = findChild<LLButton>("apply_edit_values");
|
|
llassert(mApplyEditsButton != NULL);
|
|
mApplyEditsButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyChangesClicked, this));
|
|
|
|
return LLFloaterPathfindingObjects::postBuild();
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::requestGetObjects()
|
|
{
|
|
LLPathfindingManager::getInstance()->requestGetLinksets(getNewRequestId(), boost::bind(&LLFloaterPathfindingLinksets::handleNewObjectList, this, _1, _2, _3));
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::buildObjectsScrollList(const LLPathfindingObjectListPtr pObjectListPtr)
|
|
{
|
|
llassert(pObjectListPtr != NULL);
|
|
llassert(!pObjectListPtr->isEmpty());
|
|
|
|
std::string nameFilter = mFilterByName->getText();
|
|
std::string descriptionFilter = mFilterByDescription->getText();
|
|
LLPathfindingLinkset::ELinksetUse linksetUseFilter = getFilterLinksetUse();
|
|
bool isFilteringName = !nameFilter.empty();
|
|
bool isFilteringDescription = !descriptionFilter.empty();
|
|
bool isFilteringLinksetUse = (linksetUseFilter != LLPathfindingLinkset::kUnknown);
|
|
|
|
const LLVector3& avatarPosition = gAgent.getPositionAgent();
|
|
|
|
if (isFilteringName || isFilteringDescription || isFilteringLinksetUse)
|
|
{
|
|
LLStringUtil::toUpper(nameFilter);
|
|
LLStringUtil::toUpper(descriptionFilter);
|
|
for (LLPathfindingObjectList::const_iterator objectIter = pObjectListPtr->begin(); objectIter != pObjectListPtr->end(); ++objectIter)
|
|
{
|
|
const LLPathfindingObjectPtr objectPtr = objectIter->second;
|
|
const LLPathfindingLinkset *linksetPtr = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get());
|
|
llassert(linksetPtr != NULL);
|
|
|
|
std::string linksetName = (linksetPtr->isTerrain() ? getString("linkset_terrain_name") : linksetPtr->getName());
|
|
std::string linksetDescription = linksetPtr->getDescription();
|
|
LLStringUtil::toUpper(linksetName);
|
|
LLStringUtil::toUpper(linksetDescription);
|
|
|
|
if ((!isFilteringName || (linksetName.find(nameFilter) != std::string::npos)) &&
|
|
(!isFilteringDescription || (linksetDescription.find(descriptionFilter) != std::string::npos)) &&
|
|
(!isFilteringLinksetUse || (linksetPtr->getLinksetUse() == linksetUseFilter)))
|
|
{
|
|
LLSD scrollListItemData = buildLinksetScrollListItemData(linksetPtr, avatarPosition);
|
|
addObjectToScrollList(objectPtr, scrollListItemData);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (LLPathfindingObjectList::const_iterator objectIter = pObjectListPtr->begin(); objectIter != pObjectListPtr->end(); ++objectIter)
|
|
{
|
|
const LLPathfindingObjectPtr objectPtr = objectIter->second;
|
|
const LLPathfindingLinkset *linksetPtr = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get());
|
|
llassert(linksetPtr != NULL);
|
|
|
|
LLSD scrollListItemData = buildLinksetScrollListItemData(linksetPtr, avatarPosition);
|
|
addObjectToScrollList(objectPtr, scrollListItemData);
|
|
}
|
|
}
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::updateControlsOnScrollListChange()
|
|
{
|
|
LLFloaterPathfindingObjects::updateControlsOnScrollListChange();
|
|
updateEditFieldValues();
|
|
updateStateOnEditFields();
|
|
updateStateOnEditLinksetUse();
|
|
}
|
|
|
|
S32 LLFloaterPathfindingLinksets::getNameColumnIndex() const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
S32 LLFloaterPathfindingLinksets::getOwnerNameColumnIndex() const
|
|
{
|
|
return 2;
|
|
}
|
|
|
|
std::string LLFloaterPathfindingLinksets::getOwnerName(const LLPathfindingObject *pObject) const
|
|
{
|
|
return (pObject->hasOwner()
|
|
? (pObject->hasOwnerName()
|
|
? (pObject->isGroupOwned()
|
|
? (pObject->getOwnerName() + " " + getString("linkset_owner_group"))
|
|
: pObject->getOwnerName())
|
|
: getString("linkset_owner_loading"))
|
|
: getString("linkset_owner_unknown"));
|
|
}
|
|
|
|
const LLColor4 &LLFloaterPathfindingLinksets::getBeaconColor() const
|
|
{
|
|
return mBeaconColor;
|
|
}
|
|
|
|
LLPathfindingObjectListPtr LLFloaterPathfindingLinksets::getEmptyObjectList() const
|
|
{
|
|
LLPathfindingObjectListPtr objectListPtr(new LLPathfindingLinksetList());
|
|
return objectListPtr;
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::requestSetLinksets(LLPathfindingObjectListPtr pLinksetList, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD)
|
|
{
|
|
LLPathfindingManager::getInstance()->requestSetLinksets(getNewRequestId(), pLinksetList, pLinksetUse, pA, pB, pC, pD, boost::bind(&LLFloaterPathfindingLinksets::handleUpdateObjectList, this, _1, _2, _3));
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::onApplyAllFilters()
|
|
{
|
|
rebuildObjectsScrollList();
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::onClearFiltersClicked()
|
|
{
|
|
clearFilters();
|
|
rebuildObjectsScrollList();
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered(LLUICtrl *pUICtrl, LLSD &pPreviousValue)
|
|
{
|
|
LLLineEditor *pLineEditor = static_cast<LLLineEditor *>(pUICtrl);
|
|
llassert(pLineEditor != NULL);
|
|
|
|
const std::string &valueString = pLineEditor->getText();
|
|
|
|
S32 intValue;
|
|
LLSD value;
|
|
bool doResetValue = false;
|
|
|
|
if (valueString.empty())
|
|
{
|
|
value = pPreviousValue;
|
|
doResetValue = true;
|
|
}
|
|
else if (LLStringUtil::convertToS32(valueString, intValue))
|
|
{
|
|
doResetValue = ((intValue < LLPathfindingLinkset::MIN_WALKABILITY_VALUE) || (intValue > LLPathfindingLinkset::MAX_WALKABILITY_VALUE));
|
|
value = LLSD(llclamp(intValue, LLPathfindingLinkset::MIN_WALKABILITY_VALUE, LLPathfindingLinkset::MAX_WALKABILITY_VALUE));
|
|
}
|
|
else
|
|
{
|
|
value = LLSD(LLPathfindingLinkset::MAX_WALKABILITY_VALUE);
|
|
doResetValue = true;
|
|
}
|
|
|
|
if (doResetValue)
|
|
{
|
|
pLineEditor->setValue(value);
|
|
}
|
|
pPreviousValue = value;
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::onApplyChangesClicked()
|
|
{
|
|
applyEdit();
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::clearFilters()
|
|
{
|
|
mFilterByName->clear();
|
|
mFilterByDescription->clear();
|
|
setFilterLinksetUse(LLPathfindingLinkset::kUnknown);
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::updateEditFieldValues()
|
|
{
|
|
int numSelectedObjects = getNumSelectedObjects();
|
|
if (numSelectedObjects <= 0)
|
|
{
|
|
mEditLinksetUse->selectFirstItem();
|
|
mEditA->clear();
|
|
mEditB->clear();
|
|
mEditC->clear();
|
|
mEditD->clear();
|
|
}
|
|
else
|
|
{
|
|
LLPathfindingObjectPtr firstSelectedObjectPtr = getFirstSelectedObject();
|
|
llassert(firstSelectedObjectPtr != NULL);
|
|
|
|
const LLPathfindingLinkset *linkset = dynamic_cast<const LLPathfindingLinkset *>(firstSelectedObjectPtr.get());
|
|
|
|
setEditLinksetUse(linkset->getLinksetUse());
|
|
mPreviousValueA = LLSD(linkset->getWalkabilityCoefficientA());
|
|
mPreviousValueB = LLSD(linkset->getWalkabilityCoefficientB());
|
|
mPreviousValueC = LLSD(linkset->getWalkabilityCoefficientC());
|
|
mPreviousValueD = LLSD(linkset->getWalkabilityCoefficientD());
|
|
mEditA->setValue(mPreviousValueA);
|
|
mEditB->setValue(mPreviousValueB);
|
|
mEditC->setValue(mPreviousValueC);
|
|
mEditD->setValue(mPreviousValueD);
|
|
}
|
|
}
|
|
|
|
LLSD LLFloaterPathfindingLinksets::buildLinksetScrollListItemData(const LLPathfindingLinkset *pLinksetPtr, const LLVector3 &pAvatarPosition) const
|
|
{
|
|
llassert(pLinksetPtr != NULL);
|
|
LLSD columns = LLSD::emptyArray();
|
|
|
|
if (pLinksetPtr->isTerrain())
|
|
{
|
|
columns[0]["column"] = "name";
|
|
columns[0]["value"] = getString("linkset_terrain_name");
|
|
|
|
columns[1]["column"] = "description";
|
|
columns[1]["value"] = getString("linkset_terrain_description");
|
|
|
|
columns[2]["column"] = "owner";
|
|
columns[2]["value"] = getString("linkset_terrain_owner");
|
|
|
|
columns[3]["column"] = "scripted";
|
|
columns[3]["value"] = getString("linkset_terrain_scripted");
|
|
|
|
columns[4]["column"] = "land_impact";
|
|
columns[4]["value"] = getString("linkset_terrain_land_impact");
|
|
|
|
columns[5]["column"] = "dist_from_you";
|
|
columns[5]["value"] = getString("linkset_terrain_dist_from_you");
|
|
}
|
|
else
|
|
{
|
|
columns[0]["column"] = "name";
|
|
columns[0]["value"] = pLinksetPtr->getName();
|
|
|
|
columns[1]["column"] = "description";
|
|
columns[1]["value"] = pLinksetPtr->getDescription();
|
|
|
|
columns[2]["column"] = "owner";
|
|
columns[2]["value"] = getOwnerName(pLinksetPtr);
|
|
|
|
columns[3]["column"] = "scripted";
|
|
columns[3]["value"] = (pLinksetPtr->hasIsScripted()
|
|
? (pLinksetPtr->isScripted()
|
|
? getString("linkset_is_scripted")
|
|
: getString("linkset_is_not_scripted"))
|
|
: getString("linkset_is_unknown_scripted"));
|
|
|
|
columns[4]["column"] = "land_impact";
|
|
columns[4]["value"] = llformat("%1d", pLinksetPtr->getLandImpact());
|
|
|
|
columns[5]["column"] = "dist_from_you";
|
|
columns[5]["value"] = llformat("%1.0f m", dist_vec(pAvatarPosition, pLinksetPtr->getLocation()));
|
|
}
|
|
|
|
columns[6]["column"] = "linkset_use";
|
|
std::string linksetUse = getLinksetUseString(pLinksetPtr->getLinksetUse());
|
|
if (pLinksetPtr->isTerrain())
|
|
{
|
|
linksetUse += (" " + getString("linkset_is_terrain"));
|
|
}
|
|
else if (!pLinksetPtr->isModifiable() && pLinksetPtr->canBeVolume())
|
|
{
|
|
linksetUse += (" " + getString("linkset_is_restricted_state"));
|
|
}
|
|
else if (pLinksetPtr->isModifiable() && !pLinksetPtr->canBeVolume())
|
|
{
|
|
linksetUse += (" " + getString("linkset_is_non_volume_state"));
|
|
}
|
|
else if (!pLinksetPtr->isModifiable() && !pLinksetPtr->canBeVolume())
|
|
{
|
|
linksetUse += (" " + getString("linkset_is_restricted_non_volume_state"));
|
|
}
|
|
columns[6]["value"] = linksetUse;
|
|
|
|
columns[7]["column"] = "a_percent";
|
|
columns[7]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientA());
|
|
|
|
columns[8]["column"] = "b_percent";
|
|
columns[8]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientB());
|
|
|
|
columns[9]["column"] = "c_percent";
|
|
columns[9]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientC());
|
|
|
|
columns[10]["column"] = "d_percent";
|
|
columns[10]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientD());
|
|
|
|
return columns;
|
|
}
|
|
|
|
/* Singu-Note: Unused function
|
|
LLSD LLFloaterPathfindingLinksets::buildLinksetUseScrollListData(const std::string &pLabel, S32 pValue) const
|
|
{
|
|
LLSD columns;
|
|
|
|
columns[0]["column"] = "name";
|
|
columns[0]["value"] = pLabel;
|
|
columns[0]["font"] = "SANSSERIF";
|
|
|
|
LLSD element;
|
|
element["value"] = pValue;
|
|
element["column"] = columns;
|
|
|
|
return element;
|
|
}
|
|
*/
|
|
|
|
bool LLFloaterPathfindingLinksets::isShowUnmodifiablePhantomWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
|
|
{
|
|
bool isShowWarning = false;
|
|
|
|
if (pLinksetUse != LLPathfindingLinkset::kUnknown)
|
|
{
|
|
LLPathfindingObjectListPtr selectedObjects = getSelectedObjects();
|
|
if ((selectedObjects != NULL) && !selectedObjects->isEmpty())
|
|
{
|
|
const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(selectedObjects.get());
|
|
isShowWarning = linksetList->isShowUnmodifiablePhantomWarning(pLinksetUse);
|
|
}
|
|
}
|
|
|
|
return isShowWarning;
|
|
}
|
|
|
|
bool LLFloaterPathfindingLinksets::isShowPhantomToggleWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
|
|
{
|
|
bool isShowWarning = false;
|
|
|
|
if (pLinksetUse != LLPathfindingLinkset::kUnknown)
|
|
{
|
|
LLPathfindingObjectListPtr selectedObjects = getSelectedObjects();
|
|
if ((selectedObjects != NULL) && !selectedObjects->isEmpty())
|
|
{
|
|
const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(selectedObjects.get());
|
|
isShowWarning = linksetList->isShowPhantomToggleWarning(pLinksetUse);
|
|
}
|
|
}
|
|
|
|
return isShowWarning;
|
|
}
|
|
|
|
bool LLFloaterPathfindingLinksets::isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
|
|
{
|
|
bool isShowWarning = false;
|
|
|
|
if (pLinksetUse != LLPathfindingLinkset::kUnknown)
|
|
{
|
|
LLPathfindingObjectListPtr selectedObjects = getSelectedObjects();
|
|
if ((selectedObjects != NULL) && !selectedObjects->isEmpty())
|
|
{
|
|
const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(selectedObjects.get());
|
|
isShowWarning = linksetList->isShowCannotBeVolumeWarning(pLinksetUse);
|
|
}
|
|
}
|
|
|
|
return isShowWarning;
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::updateStateOnEditFields()
|
|
{
|
|
int numSelectedItems = getNumSelectedObjects();
|
|
bool isEditEnabled = (numSelectedItems > 0);
|
|
|
|
mEditLinksetUse->setEnabled(isEditEnabled);
|
|
|
|
mLabelWalkabilityCoefficients->setEnabled(isEditEnabled);
|
|
mLabelEditA->setEnabled(isEditEnabled);
|
|
mLabelEditB->setEnabled(isEditEnabled);
|
|
mLabelEditC->setEnabled(isEditEnabled);
|
|
mLabelEditD->setEnabled(isEditEnabled);
|
|
mLabelSuggestedUseA->setEnabled(isEditEnabled);
|
|
mLabelSuggestedUseB->setEnabled(isEditEnabled);
|
|
mLabelSuggestedUseC->setEnabled(isEditEnabled);
|
|
mLabelSuggestedUseD->setEnabled(isEditEnabled);
|
|
mEditA->setEnabled(isEditEnabled);
|
|
mEditB->setEnabled(isEditEnabled);
|
|
mEditC->setEnabled(isEditEnabled);
|
|
mEditD->setEnabled(isEditEnabled);
|
|
|
|
mApplyEditsButton->setEnabled(isEditEnabled && (getMessagingState() == kMessagingComplete));
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::updateStateOnEditLinksetUse()
|
|
{
|
|
BOOL useWalkable = FALSE;
|
|
BOOL useStaticObstacle = FALSE;
|
|
BOOL useDynamicObstacle = FALSE;
|
|
BOOL useMaterialVolume = FALSE;
|
|
BOOL useExclusionVolume = FALSE;
|
|
BOOL useDynamicPhantom = FALSE;
|
|
|
|
LLPathfindingObjectListPtr selectedObjects = getSelectedObjects();
|
|
if ((selectedObjects != NULL) && !selectedObjects->isEmpty())
|
|
{
|
|
const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(selectedObjects.get());
|
|
linksetList->determinePossibleStates(useWalkable, useStaticObstacle, useDynamicObstacle, useMaterialVolume, useExclusionVolume, useDynamicPhantom);
|
|
}
|
|
|
|
mEditLinksetUseWalkable->setEnabled(useWalkable);
|
|
mEditLinksetUseStaticObstacle->setEnabled(useStaticObstacle);
|
|
mEditLinksetUseDynamicObstacle->setEnabled(useDynamicObstacle);
|
|
mEditLinksetUseMaterialVolume->setEnabled(useMaterialVolume);
|
|
mEditLinksetUseExclusionVolume->setEnabled(useExclusionVolume);
|
|
mEditLinksetUseDynamicPhantom->setEnabled(useDynamicPhantom);
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::applyEdit()
|
|
{
|
|
LLPathfindingLinkset::ELinksetUse linksetUse = getEditLinksetUse();
|
|
|
|
bool showPhantomToggleWarning = isShowPhantomToggleWarning(linksetUse);
|
|
bool showUnmodifiablePhantomWarning = isShowUnmodifiablePhantomWarning(linksetUse);
|
|
bool showCannotBeVolumeWarning = isShowCannotBeVolumeWarning(linksetUse);
|
|
|
|
if (showPhantomToggleWarning || showUnmodifiablePhantomWarning || showCannotBeVolumeWarning)
|
|
{
|
|
LLPathfindingLinkset::ELinksetUse restrictedLinksetUse = LLPathfindingLinkset::getLinksetUseWithToggledPhantom(linksetUse);
|
|
LLSD substitutions;
|
|
substitutions["REQUESTED_TYPE"] = getLinksetUseString(linksetUse);
|
|
substitutions["RESTRICTED_TYPE"] = getLinksetUseString(restrictedLinksetUse);
|
|
|
|
// Build one of the following notifications names
|
|
// - PathfindingLinksets_WarnOnPhantom
|
|
// - PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted
|
|
// - PathfindingLinksets_WarnOnPhantom_MismatchOnVolume
|
|
// - PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume
|
|
// - PathfindingLinksets_MismatchOnRestricted
|
|
// - PathfindingLinksets_MismatchOnVolume
|
|
// - PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume
|
|
|
|
std::string notificationName = "PathfindingLinksets";
|
|
|
|
if (showPhantomToggleWarning)
|
|
{
|
|
notificationName += "_WarnOnPhantom";
|
|
}
|
|
if (showUnmodifiablePhantomWarning)
|
|
{
|
|
notificationName += "_MismatchOnRestricted";
|
|
}
|
|
if (showCannotBeVolumeWarning)
|
|
{
|
|
notificationName += "_MismatchOnVolume";
|
|
}
|
|
|
|
LLNotificationsUtil::add(notificationName, substitutions, LLSD(), boost::bind(&LLFloaterPathfindingLinksets::handleApplyEdit, this, _1, _2));
|
|
}
|
|
else
|
|
{
|
|
doApplyEdit();
|
|
}
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::handleApplyEdit(const LLSD &pNotification, const LLSD &pResponse)
|
|
{
|
|
if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0)
|
|
{
|
|
doApplyEdit();
|
|
}
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::doApplyEdit()
|
|
{
|
|
LLPathfindingObjectListPtr selectedObjects = getSelectedObjects();
|
|
if ((selectedObjects != NULL) && !selectedObjects->isEmpty())
|
|
{
|
|
LLPathfindingLinkset::ELinksetUse linksetUse = getEditLinksetUse();
|
|
const std::string &aString = mEditA->getText();
|
|
const std::string &bString = mEditB->getText();
|
|
const std::string &cString = mEditC->getText();
|
|
const std::string &dString = mEditD->getText();
|
|
S32 aValue = static_cast<S32>(atoi(aString.c_str()));
|
|
S32 bValue = static_cast<S32>(atoi(bString.c_str()));
|
|
S32 cValue = static_cast<S32>(atoi(cString.c_str()));
|
|
S32 dValue = static_cast<S32>(atoi(dString.c_str()));
|
|
|
|
|
|
requestSetLinksets(selectedObjects, linksetUse, aValue, bValue, cValue, dValue);
|
|
}
|
|
}
|
|
|
|
std::string LLFloaterPathfindingLinksets::getLinksetUseString(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
|
|
{
|
|
std::string linksetUse;
|
|
|
|
switch (pLinksetUse)
|
|
{
|
|
case LLPathfindingLinkset::kWalkable :
|
|
linksetUse = getString("linkset_use_walkable");
|
|
break;
|
|
case LLPathfindingLinkset::kStaticObstacle :
|
|
linksetUse = getString("linkset_use_static_obstacle");
|
|
break;
|
|
case LLPathfindingLinkset::kDynamicObstacle :
|
|
linksetUse = getString("linkset_use_dynamic_obstacle");
|
|
break;
|
|
case LLPathfindingLinkset::kMaterialVolume :
|
|
linksetUse = getString("linkset_use_material_volume");
|
|
break;
|
|
case LLPathfindingLinkset::kExclusionVolume :
|
|
linksetUse = getString("linkset_use_exclusion_volume");
|
|
break;
|
|
case LLPathfindingLinkset::kDynamicPhantom :
|
|
linksetUse = getString("linkset_use_dynamic_phantom");
|
|
break;
|
|
case LLPathfindingLinkset::kUnknown :
|
|
default :
|
|
linksetUse = getString("linkset_use_dynamic_obstacle");
|
|
llassert(0);
|
|
break;
|
|
}
|
|
|
|
return linksetUse;
|
|
}
|
|
|
|
LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::getFilterLinksetUse() const
|
|
{
|
|
return convertToLinksetUse(mFilterByLinksetUse->getValue());
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::setFilterLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse)
|
|
{
|
|
mFilterByLinksetUse->setValue(convertToXuiValue(pLinksetUse));
|
|
}
|
|
|
|
LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::getEditLinksetUse() const
|
|
{
|
|
return convertToLinksetUse(mEditLinksetUse->getValue());
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::setEditLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse)
|
|
{
|
|
mEditLinksetUse->setValue(convertToXuiValue(pLinksetUse));
|
|
}
|
|
|
|
LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::convertToLinksetUse(LLSD pXuiValue) const
|
|
{
|
|
LLPathfindingLinkset::ELinksetUse linkUse;
|
|
|
|
switch (pXuiValue.asInteger())
|
|
{
|
|
case XUI_LINKSET_USE_NONE :
|
|
linkUse = LLPathfindingLinkset::kUnknown;
|
|
break;
|
|
case XUI_LINKSET_USE_WALKABLE :
|
|
linkUse = LLPathfindingLinkset::kWalkable;
|
|
break;
|
|
case XUI_LINKSET_USE_STATIC_OBSTACLE :
|
|
linkUse = LLPathfindingLinkset::kStaticObstacle;
|
|
break;
|
|
case XUI_LINKSET_USE_DYNAMIC_OBSTACLE :
|
|
linkUse = LLPathfindingLinkset::kDynamicObstacle;
|
|
break;
|
|
case XUI_LINKSET_USE_MATERIAL_VOLUME :
|
|
linkUse = LLPathfindingLinkset::kMaterialVolume;
|
|
break;
|
|
case XUI_LINKSET_USE_EXCLUSION_VOLUME :
|
|
linkUse = LLPathfindingLinkset::kExclusionVolume;
|
|
break;
|
|
case XUI_LINKSET_USE_DYNAMIC_PHANTOM :
|
|
linkUse = LLPathfindingLinkset::kDynamicPhantom;
|
|
break;
|
|
default :
|
|
linkUse = LLPathfindingLinkset::kUnknown;
|
|
llassert(0);
|
|
break;
|
|
}
|
|
|
|
return linkUse;
|
|
}
|
|
|
|
LLSD LLFloaterPathfindingLinksets::convertToXuiValue(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
|
|
{
|
|
LLSD xuiValue;
|
|
|
|
switch (pLinksetUse)
|
|
{
|
|
case LLPathfindingLinkset::kUnknown :
|
|
xuiValue = XUI_LINKSET_USE_NONE;
|
|
break;
|
|
case LLPathfindingLinkset::kWalkable :
|
|
xuiValue = XUI_LINKSET_USE_WALKABLE;
|
|
break;
|
|
case LLPathfindingLinkset::kStaticObstacle :
|
|
xuiValue = XUI_LINKSET_USE_STATIC_OBSTACLE;
|
|
break;
|
|
case LLPathfindingLinkset::kDynamicObstacle :
|
|
xuiValue = XUI_LINKSET_USE_DYNAMIC_OBSTACLE;
|
|
break;
|
|
case LLPathfindingLinkset::kMaterialVolume :
|
|
xuiValue = XUI_LINKSET_USE_MATERIAL_VOLUME;
|
|
break;
|
|
case LLPathfindingLinkset::kExclusionVolume :
|
|
xuiValue = XUI_LINKSET_USE_EXCLUSION_VOLUME;
|
|
break;
|
|
case LLPathfindingLinkset::kDynamicPhantom :
|
|
xuiValue = XUI_LINKSET_USE_DYNAMIC_PHANTOM;
|
|
break;
|
|
default :
|
|
xuiValue = XUI_LINKSET_USE_NONE;
|
|
llassert(0);
|
|
break;
|
|
}
|
|
|
|
return xuiValue;
|
|
}
|