PATH-292: Adding better usability and warning notifications for the handling of locked linksets.

master
Todd Stinson 2012-02-27 15:43:58 -08:00
parent 3b4e4f8bc9
commit 518bc51e66
6 changed files with 298 additions and 89 deletions

View File

@ -50,6 +50,7 @@
#include "llpathfindinglinkset.h"
#include "llpathfindinglinksetlist.h"
#include "llpathfindingmanager.h"
#include "llnotificationsutil.h"
#include <boost/bind.hpp>
@ -132,6 +133,31 @@ BOOL LLFloaterPathfindingLinksets::postBuild()
mEditLinksetUse = findChild<LLComboBox>("edit_linkset_use");
llassert(mEditLinksetUse != NULL);
mEditLinksetUse->clearRows();
mEditLinksetUseUnset = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getString("linkset_choose_use"), XUI_LINKSET_USE_NONE));
llassert(mEditLinksetUseUnset != NULL);
mEditLinksetUseWalkable = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getLinksetUseString(LLPathfindingLinkset::kWalkable), XUI_LINKSET_USE_WALKABLE));
llassert(mEditLinksetUseWalkable != NULL);
mEditLinksetUseStaticObstacle = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getLinksetUseString(LLPathfindingLinkset::kStaticObstacle), XUI_LINKSET_USE_STATIC_OBSTACLE));
llassert(mEditLinksetUseStaticObstacle != NULL);
mEditLinksetUseDynamicObstacle = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getLinksetUseString(LLPathfindingLinkset::kDynamicObstacle), XUI_LINKSET_USE_DYNAMIC_OBSTACLE));
llassert(mEditLinksetUseDynamicObstacle != NULL);
mEditLinksetUseMaterialVolume = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getLinksetUseString(LLPathfindingLinkset::kMaterialVolume), XUI_LINKSET_USE_MATERIAL_VOLUME));
llassert(mEditLinksetUseMaterialVolume != NULL);
mEditLinksetUseExclusionVolume = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getLinksetUseString(LLPathfindingLinkset::kExclusionVolume), XUI_LINKSET_USE_EXCLUSION_VOLUME));
llassert(mEditLinksetUseExclusionVolume != NULL);
mEditLinksetUseDynamicPhantom = mEditLinksetUse->addElement(buildLinksetUseScrollListElement(getLinksetUseString(LLPathfindingLinkset::kDynamicPhantom), XUI_LINKSET_USE_DYNAMIC_PHANTOM));
llassert(mEditLinksetUseDynamicPhantom != NULL);
mEditLinksetUse->selectFirstItem();
mLabelWalkabilityCoefficients = findChild<LLTextBase>("walkability_coefficients_label");
llassert(mLabelWalkabilityCoefficients != NULL);
@ -570,7 +596,7 @@ void LLFloaterPathfindingLinksets::updateEditFieldValues()
int numSelectedItems = selectedItems.size();
if (numSelectedItems <= 0)
{
mEditLinksetUse->clear();
mEditLinksetUse->selectFirstItem();
mEditA->clear();
mEditB->clear();
mEditC->clear();
@ -589,6 +615,37 @@ void LLFloaterPathfindingLinksets::updateEditFieldValues()
mEditB->setValue(LLSD(linksetPtr->getWalkabilityCoefficientB()));
mEditC->setValue(LLSD(linksetPtr->getWalkabilityCoefficientC()));
mEditD->setValue(LLSD(linksetPtr->getWalkabilityCoefficientD()));
switch (getAllowLinksetUse())
{
case kAllowLinksetUseAll :
mEditLinksetUseWalkable->setEnabled(TRUE);
mEditLinksetUseStaticObstacle->setEnabled(TRUE);
mEditLinksetUseDynamicObstacle->setEnabled(TRUE);
mEditLinksetUseMaterialVolume->setEnabled(TRUE);
mEditLinksetUseExclusionVolume->setEnabled(TRUE);
mEditLinksetUseDynamicPhantom->setEnabled(TRUE);
break;
case kAllowLinksetUseOnlyNonPhantom :
mEditLinksetUseWalkable->setEnabled(TRUE);
mEditLinksetUseStaticObstacle->setEnabled(TRUE);
mEditLinksetUseDynamicObstacle->setEnabled(TRUE);
mEditLinksetUseMaterialVolume->setEnabled(FALSE);
mEditLinksetUseExclusionVolume->setEnabled(FALSE);
mEditLinksetUseDynamicPhantom->setEnabled(FALSE);
break;
case kAllowLinksetUseOnlyPhantom :
mEditLinksetUseWalkable->setEnabled(FALSE);
mEditLinksetUseStaticObstacle->setEnabled(FALSE);
mEditLinksetUseDynamicObstacle->setEnabled(FALSE);
mEditLinksetUseMaterialVolume->setEnabled(TRUE);
mEditLinksetUseExclusionVolume->setEnabled(TRUE);
mEditLinksetUseDynamicPhantom->setEnabled(TRUE);
break;
default :
llassert(0);
break;
}
}
}
@ -637,7 +694,7 @@ void LLFloaterPathfindingLinksets::updateScrollList()
(!isFilteringDescription || (linksetDescription.find(descriptionFilter) != std::string::npos)) &&
(!isFilteringLinksetUse || (linksetPtr->getLinksetUse() == linksetUseFilter)))
{
LLSD element = buildScrollListElement(linksetPtr, avatarPosition);
LLSD element = buildLinksetScrollListElement(linksetPtr, avatarPosition);
mLinksetsScrollList->addElement(element);
}
}
@ -648,7 +705,7 @@ void LLFloaterPathfindingLinksets::updateScrollList()
linksetIter != mLinksetsListPtr->end(); ++linksetIter)
{
const LLPathfindingLinksetPtr linksetPtr(linksetIter->second);
LLSD element = buildScrollListElement(linksetPtr, avatarPosition);
LLSD element = buildLinksetScrollListElement(linksetPtr, avatarPosition);
mLinksetsScrollList->addElement(element);
}
}
@ -659,7 +716,7 @@ void LLFloaterPathfindingLinksets::updateScrollList()
updateControls();
}
LLSD LLFloaterPathfindingLinksets::buildScrollListElement(const LLPathfindingLinksetPtr pLinksetPtr, const LLVector3 &pAvatarPosition)
LLSD LLFloaterPathfindingLinksets::buildLinksetScrollListElement(const LLPathfindingLinksetPtr pLinksetPtr, const LLVector3 &pAvatarPosition) const
{
LLSD columns;
@ -701,33 +758,7 @@ LLSD LLFloaterPathfindingLinksets::buildScrollListElement(const LLPathfindingLin
}
columns[4]["column"] = "linkset_use";
std::string linksetUse;
switch (pLinksetPtr->getLinksetUse())
{
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;
}
std::string linksetUse = getLinksetUseString(pLinksetPtr->getLinksetUse());
if (pLinksetPtr->isLocked())
{
linksetUse += (" " + getString("linkset_is_locked_state"));
@ -758,6 +789,99 @@ LLSD LLFloaterPathfindingLinksets::buildScrollListElement(const LLPathfindingLin
return element;
}
LLSD LLFloaterPathfindingLinksets::buildLinksetUseScrollListElement(const std::string &label, S32 value) const
{
LLSD columns;
columns[0]["column"] = "name";
columns[0]["relwidth"] = static_cast<LLSD::Real>(100.0f);
columns[0]["value"] = label;
columns[0]["font"] = "SANSSERIF";
LLSD element;
element["value"] = value;
element["column"] = columns;
return element;
}
LLFloaterPathfindingLinksets::EAllowLinksetsUse LLFloaterPathfindingLinksets::getAllowLinksetUse() const
{
EAllowLinksetsUse allowLinksetUse = kAllowLinksetUseAll;
std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected();
if (!selectedItems.empty())
{
bool isAllLocked = true;
bool isAllPhantom = true;
bool isAllNonPhantom = true;
for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin();
(isAllLocked || isAllPhantom || isAllNonPhantom) && (selectedItemIter != selectedItems.end()); ++selectedItemIter)
{
const LLScrollListItem *selectedItem = *selectedItemIter;
llassert(mLinksetsListPtr != NULL);
LLPathfindingLinksetList::const_iterator linksetIter = mLinksetsListPtr->find(selectedItem->getUUID().asString());
llassert(linksetIter != mLinksetsListPtr->end());
const LLPathfindingLinksetPtr linksetPtr = linksetIter->second;
if (linksetPtr->isLocked())
{
if (linksetPtr->isPhantom())
{
isAllNonPhantom = false;
}
else
{
isAllPhantom = false;
}
}
else
{
isAllLocked = false;
}
}
if (isAllLocked)
{
if (isAllPhantom && !isAllNonPhantom)
{
allowLinksetUse = kAllowLinksetUseOnlyPhantom;
}
else if (isAllNonPhantom && !isAllPhantom)
{
allowLinksetUse = kAllowLinksetUseOnlyNonPhantom;
}
}
}
return allowLinksetUse;
}
bool LLFloaterPathfindingLinksets::doShowLinksetUseSetWarning(LLPathfindingLinkset::ELinksetUse linksetUse) const
{
bool showWarning = false;
if (linksetUse != LLPathfindingLinkset::kUnknown)
{
std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected();
if (!selectedItems.empty())
{
for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin();
!showWarning && (selectedItemIter != selectedItems.end()); ++selectedItemIter)
{
const LLScrollListItem *selectedItem = *selectedItemIter;
llassert(mLinksetsListPtr != NULL);
LLPathfindingLinksetList::const_iterator linksetIter = mLinksetsListPtr->find(selectedItem->getUUID().asString());
llassert(linksetIter != mLinksetsListPtr->end());
const LLPathfindingLinksetPtr linksetPtr = linksetIter->second;
showWarning = (linksetPtr->isLocked() && (linksetPtr->isPhantom() != LLPathfindingLinkset::isPhantom(linksetUse)));
}
}
}
return showWarning;
}
void LLFloaterPathfindingLinksets::updateStatusMessage()
{
static const LLColor4 warningColor = LLUIColorTable::instance().getColor("DrYellow");
@ -881,6 +1005,32 @@ void LLFloaterPathfindingLinksets::updateEnableStateOnEditFields()
}
void LLFloaterPathfindingLinksets::applyEdit()
{
LLPathfindingLinkset::ELinksetUse linksetUse = getEditLinksetUse();
if (doShowLinksetUseSetWarning(linksetUse))
{
LLPathfindingLinkset::ELinksetUse restrictedLinksetUse = LLPathfindingLinkset::getLinksetUseWithToggledPhantom(linksetUse);
LLSD substitutions;
substitutions["REQUESTED_TYPE"] = getLinksetUseString(linksetUse);
substitutions["RESTRICTED_TYPE"] = getLinksetUseString(restrictedLinksetUse);
LLNotificationsUtil::add("PathfindingLinksets_SetLinksetUseMismatchOnRestricted", 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()
{
std::vector<LLScrollListItem*> selectedItems = mLinksetsScrollList->getAllSelected();
if (!selectedItems.empty())
@ -913,6 +1063,40 @@ void LLFloaterPathfindingLinksets::applyEdit()
}
}
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());

View File

@ -39,6 +39,7 @@ class LLSD;
class LLUICtrl;
class LLTextBase;
class LLScrollListCtrl;
class LLScrollListItem;
class LLLineEditor;
class LLComboBox;
class LLCheckBoxCtrl;
@ -74,6 +75,13 @@ public:
protected:
private:
typedef enum
{
kAllowLinksetUseAll,
kAllowLinksetUseOnlyNonPhantom,
kAllowLinksetUseOnlyPhantom
} EAllowLinksetsUse;
LLLineEditor *mFilterByName;
LLLineEditor *mFilterByDescription;
LLComboBox *mFilterByLinksetUse;
@ -89,6 +97,13 @@ private:
LLButton *mDeleteButton;
LLButton *mTeleportButton;
LLComboBox *mEditLinksetUse;
LLScrollListItem *mEditLinksetUseUnset;
LLScrollListItem *mEditLinksetUseWalkable;
LLScrollListItem *mEditLinksetUseStaticObstacle;
LLScrollListItem *mEditLinksetUseDynamicObstacle;
LLScrollListItem *mEditLinksetUseMaterialVolume;
LLScrollListItem *mEditLinksetUseExclusionVolume;
LLScrollListItem *mEditLinksetUseDynamicPhantom;
LLTextBase *mLabelWalkabilityCoefficients;
LLTextBase *mLabelEditA;
LLLineEditor *mEditA;
@ -141,13 +156,21 @@ private:
void updateControls();
void updateEditFieldValues();
void updateScrollList();
LLSD buildScrollListElement(const LLPathfindingLinksetPtr pLinksetPtr, const LLVector3 &pAvatarPosition);
LLSD buildLinksetScrollListElement(const LLPathfindingLinksetPtr pLinksetPtr, const LLVector3 &pAvatarPosition) const;
LLSD buildLinksetUseScrollListElement(const std::string &label, S32 value) const;
EAllowLinksetsUse getAllowLinksetUse() const;
bool doShowLinksetUseSetWarning(LLPathfindingLinkset::ELinksetUse linksetUse) const;
void updateStatusMessage();
void updateEnableStateOnListActions();
void updateEnableStateOnEditFields();
void applyEdit();
void handleApplyEdit(const LLSD &pNotification, const LLSD &pResponse);
void doApplyEdit();
std::string getLinksetUseString(LLPathfindingLinkset::ELinksetUse pLinksetUse) const;
LLPathfindingLinkset::ELinksetUse getFilterLinksetUse() const;
void setFilterLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse);

View File

@ -122,6 +122,46 @@ LLPathfindingLinkset& LLPathfindingLinkset::operator =(const LLPathfindingLinkse
return *this;
}
BOOL LLPathfindingLinkset::isPhantom() const
{
return isPhantom(getLinksetUse());
}
BOOL LLPathfindingLinkset::isPhantom(ELinksetUse pLinksetUse)
{
BOOL retVal;
switch (pLinksetUse)
{
case kWalkable :
case kStaticObstacle :
case kDynamicObstacle :
retVal = false;
break;
case kMaterialVolume :
case kExclusionVolume :
case kDynamicPhantom :
retVal = true;
break;
case kUnknown :
default :
retVal = false;
llassert(0);
break;
}
return retVal;
}
LLPathfindingLinkset::ELinksetUse LLPathfindingLinkset::getLinksetUseWithToggledPhantom(ELinksetUse pLinksetUse)
{
BOOL isPhantom = LLPathfindingLinkset::isPhantom(pLinksetUse);
BOOL isPermanent = LLPathfindingLinkset::isPermanent(pLinksetUse);
BOOL isWalkable = LLPathfindingLinkset::isWalkable(pLinksetUse);
return getLinksetUse(!isPhantom, isPermanent, isWalkable);
}
LLSD LLPathfindingLinkset::encodeAlteredFields(ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const
{
LLSD itemData;
@ -233,32 +273,6 @@ LLPathfindingLinkset::ELinksetUse LLPathfindingLinkset::getLinksetUse(bool pIsPh
(pIsPermanent ? (pIsWalkable ? kWalkable : kStaticObstacle) : kDynamicObstacle));
}
BOOL LLPathfindingLinkset::isPhantom(ELinksetUse pLinksetUse)
{
BOOL retVal;
switch (pLinksetUse)
{
case kWalkable :
case kStaticObstacle :
case kDynamicObstacle :
retVal = false;
break;
case kMaterialVolume :
case kExclusionVolume :
case kDynamicPhantom :
retVal = true;
break;
case kUnknown :
default :
retVal = false;
llassert(0);
break;
}
return retVal;
}
BOOL LLPathfindingLinkset::isPermanent(ELinksetUse pLinksetUse)
{
BOOL retVal;

View File

@ -66,6 +66,9 @@ public:
inline U32 getLandImpact() const {return mLandImpact;};
inline const LLVector3& getLocation() const {return mLocation;};
BOOL isLocked() const {return mIsLocked;};
BOOL isPhantom() const;
static BOOL isPhantom(ELinksetUse pLinksetUse);
static ELinksetUse getLinksetUseWithToggledPhantom(ELinksetUse pLinksetUse);
inline ELinksetUse getLinksetUse() const {return mLinksetUse;};
@ -85,7 +88,6 @@ private:
void parseObjectData(const LLSD &pLinksetItem);
void parsePathfindingData(const LLSD &pLinksetItem);
static ELinksetUse getLinksetUse(bool pIsPhantom, bool pIsPermanent, bool pIsWalkable);
static BOOL isPhantom(ELinksetUse pLinksetUse);
static BOOL isPermanent(ELinksetUse pLinksetUse);
static BOOL isWalkable(ELinksetUse pLinksetUse);

View File

@ -32,7 +32,8 @@
<floater.string name="linkset_use_material_volume">Material volume</floater.string>
<floater.string name="linkset_use_exclusion_volume">Exclusion volume</floater.string>
<floater.string name="linkset_use_dynamic_phantom">Dynamic phantom</floater.string>
<floater.string name="linkset_is_locked_state">[locked]</floater.string>
<floater.string name="linkset_is_locked_state">[restricted]</floater.string>
<floater.string name="linkset_choose_use">Choose linkset use...</floater.string>
<panel
border="false"
bevel_style="none"
@ -373,34 +374,6 @@
left="18"
top_pad="17"
width="199">
<combo_box.item
label="Choose linkset use..."
name="edit_linkset_use_none"
value="0" />
<combo_box.item
label="Walkable"
name="edit_linkset_use_walkable"
value="1" />
<combo_box.item
label="Static obstacle"
name="edit_linkset_use_static_obstacle"
value="2" />
<combo_box.item
label="Dynamic obstacle"
name="edit_linkset_use_dynamic_obstacle"
value="3" />
<combo_box.item
label="Material volume"
name="edit_linkset_use_material_volume"
value="4" />
<combo_box.item
label="Exclusion volume"
name="edit_linkset_use_exclusion_volume"
value="5" />
<combo_box.item
label="Dynamic phantom"
name="edit_linkset_use_dynamic_phantom"
value="6" />
</combo_box>
<text
height="13"

View File

@ -7663,7 +7663,20 @@ The site at &apos;&lt;nolink&gt;[HOST_NAME]&lt;/nolink&gt;&apos; in realm &apos;
notext="Cancel"
ignoretext="Confirm before hiding UI"/>
</notification>
<notification
icon="alertmodal.tga"
name="PathfindingLinksets_SetLinksetUseMismatchOnRestricted"
type="alertmodal">
Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because of permission restrictions on the linkset. These linksets will be set to be '[RESTRICTED_TYPE]' instead.
<tag>confirm</tag>
<usetemplate
ignoretext="Do you wish to proceed?"
name="okcancelignore"
notext="Cancel"
yestext="OK"/>
</notification>
<global name="UnsupportedGLRequirements">
You do not appear to have the proper hardware requirements for [APP_NAME]. [APP_NAME] requires an OpenGL graphics card that has multitexture support. If this is the case, you may want to make sure that you have the latest drivers for your graphics card, and service packs and patches for your operating system.