From c0c642862e8e4b58e185aafdd29460c7a89c6483 Mon Sep 17 00:00:00 2001 From: Todd Stinson Date: Wed, 11 Jan 2012 17:44:49 -0800 Subject: PATH-145: Implementing the basics of filtering on the pathfinding linksets console. Still need some refinments in usability. --- indra/newview/llfloaterpathfindinglinksets.cpp | 352 +++++++++++++++++---- indra/newview/llfloaterpathfindinglinksets.h | 57 +++- .../xui/en/floater_pathfinding_linksets.xml | 12 +- 3 files changed, 341 insertions(+), 80 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llfloaterpathfindinglinksets.cpp b/indra/newview/llfloaterpathfindinglinksets.cpp index 699e105a31..af9eda51cd 100644 --- a/indra/newview/llfloaterpathfindinglinksets.cpp +++ b/indra/newview/llfloaterpathfindinglinksets.cpp @@ -33,11 +33,13 @@ #include "llagent.h" #include "llfloater.h" #include "llfloaterreg.h" +#include "lltextbase.h" +#include "lllineeditor.h" #include "llscrolllistctrl.h" +#include "llcheckboxctrl.h" #include "llresmgr.h" #include "llviewerregion.h" #include "llhttpclient.h" -#include "lltextbase.h" #include "lluuid.h" //--------------------------------------------------------------------------- @@ -257,6 +259,83 @@ void PathfindingLinkset::setD(F32 pD) mD = pD; } +//--------------------------------------------------------------------------- +// FilterString +//--------------------------------------------------------------------------- + +FilterString::FilterString() + : mFilter(), + mUpperFilter() +{ +} + +FilterString::FilterString(const std::string& pFilter) + : mFilter(pFilter), + mUpperFilter() +{ + LLStringUtil::trim(mFilter); + mUpperFilter = mFilter; + if (!mUpperFilter.empty()) + { + LLStringUtil::toUpper(mUpperFilter); + } +} + +FilterString::FilterString(const FilterString& pOther) + : mFilter(pOther.mFilter), + mUpperFilter(pOther.mUpperFilter) +{ +} + +FilterString::~FilterString() +{ +} + +const std::string& FilterString::get() const +{ + return mFilter; +} + +bool FilterString::set(const std::string& pFilter) +{ + std::string newFilter(pFilter); + LLStringUtil::trim(newFilter); + bool didFilterChange = (mFilter.compare(newFilter) != 0); + if (didFilterChange) + { + mFilter = newFilter; + mUpperFilter = newFilter; + LLStringUtil::toUpper(mUpperFilter); + } + + return didFilterChange; +} + +void FilterString::clear() +{ + mFilter.clear(); + mUpperFilter.clear(); +} + +bool FilterString::isActive() const +{ + return !mFilter.empty(); +} + +bool FilterString::doesMatch(const std::string& pTestString) const +{ + bool doesMatch = true; + + if (isActive()) + { + std::string upperTestString(pTestString); + LLStringUtil::toUpper(upperTestString); + doesMatch = (upperTestString.find(mUpperFilter) != std::string::npos); + } + + return doesMatch; +} + //--------------------------------------------------------------------------- // PathfindingLinksets //--------------------------------------------------------------------------- @@ -264,16 +343,22 @@ void PathfindingLinkset::setD(F32 pD) PathfindingLinksets::PathfindingLinksets() : mAllLinksets(), mFilteredLinksets(), - mIsFilterDirty(false), - mNameFilter() + mIsFiltersDirty(false), + mNameFilter(), + mDescriptionFilter(), + mIsFixedFilter(false), + mIsWalkableFilter(false) { } PathfindingLinksets::PathfindingLinksets(const LLSD& pNavmeshData) : mAllLinksets(), mFilteredLinksets(), - mIsFilterDirty(false), - mNameFilter() + mIsFiltersDirty(false), + mNameFilter(), + mDescriptionFilter(), + mIsFixedFilter(false), + mIsWalkableFilter(false) { parseNavmeshData(pNavmeshData); } @@ -281,8 +366,11 @@ PathfindingLinksets::PathfindingLinksets(const LLSD& pNavmeshData) PathfindingLinksets::PathfindingLinksets(const PathfindingLinksets& pOther) : mAllLinksets(pOther.mAllLinksets), mFilteredLinksets(pOther.mFilteredLinksets), - mIsFilterDirty(pOther.mIsFilterDirty), - mNameFilter(pOther.mNameFilter) + mIsFiltersDirty(pOther.mIsFiltersDirty), + mNameFilter(pOther.mNameFilter), + mDescriptionFilter(pOther.mDescriptionFilter), + mIsFixedFilter(pOther.mIsFixedFilter), + mIsWalkableFilter(pOther.mIsWalkableFilter) { } @@ -305,14 +393,14 @@ void PathfindingLinksets::parseNavmeshData(const LLSD& pNavmeshData) mAllLinksets.insert(std::pair(uuid, linkset)); } - mIsFilterDirty = true; + mIsFiltersDirty = true; } void PathfindingLinksets::clearLinksets() { mAllLinksets.clear(); mFilteredLinksets.clear(); - mIsFilterDirty = false; + mIsFiltersDirty = false; } const PathfindingLinksets::PathfindingLinksetMap& PathfindingLinksets::getAllLinksets() const @@ -322,28 +410,97 @@ const PathfindingLinksets::PathfindingLinksetMap& PathfindingLinksets::getAllLin const PathfindingLinksets::PathfindingLinksetMap& PathfindingLinksets::getFilteredLinksets() { -#if 0 - if (!isFilterActive()) + if (!isFiltersActive()) { return mAllLinksets; } else { - if (mIsFilterDirty) - { - mFilteredLinksets.clear(); - for (PathfindingLinksetMap::const_iterator linksetIter = mAllLinksets.begin(); - linksetIter != mAllLinksets.end(); ++linksetIter) - { + applyFilters(); + return mFilteredLinksets; + } +} - } - mIsFilterDirty = false; +BOOL PathfindingLinksets::isFiltersActive() const +{ + return (mNameFilter.isActive() || mDescriptionFilter.isActive() || mIsFixedFilter || mIsWalkableFilter); +} + +void PathfindingLinksets::setNameFilter(const std::string& pNameFilter) +{ + mIsFiltersDirty = (mNameFilter.set(pNameFilter) || mIsFiltersDirty); +} + +const std::string& PathfindingLinksets::getNameFilter() const +{ + return mNameFilter.get(); +} + +void PathfindingLinksets::setDescriptionFilter(const std::string& pDescriptionFilter) +{ + mIsFiltersDirty = (mDescriptionFilter.set(pDescriptionFilter) || mIsFiltersDirty); +} + +const std::string& PathfindingLinksets::getDescriptionFilter() const +{ + return mDescriptionFilter.get(); +} + +void PathfindingLinksets::setFixedFilter(BOOL pFixedFilter) +{ + mIsFiltersDirty = (mIsFiltersDirty || (mIsFixedFilter == pFixedFilter)); + mIsFixedFilter = pFixedFilter; +} + +BOOL PathfindingLinksets::isFixedFilter() const +{ + return mIsFixedFilter; +} + +void PathfindingLinksets::setWalkableFilter(BOOL pWalkableFilter) +{ + mIsFiltersDirty = (mIsFiltersDirty || (mIsWalkableFilter == pWalkableFilter)); + mIsWalkableFilter = pWalkableFilter; +} + +BOOL PathfindingLinksets::isWalkableFilter() const +{ + return mIsWalkableFilter; +} + +void PathfindingLinksets::clearFilters() +{ + mNameFilter.clear(); + mDescriptionFilter.clear(); + mIsFixedFilter = false; + mIsWalkableFilter = false; + mIsFiltersDirty = false; +} + +void PathfindingLinksets::applyFilters() +{ + mFilteredLinksets.clear(); + + for (PathfindingLinksetMap::const_iterator linksetIter = mAllLinksets.begin(); + linksetIter != mAllLinksets.end(); ++linksetIter) + { + const std::string& uuid(linksetIter->first); + const PathfindingLinkset& linkset(linksetIter->second); + if (doesMatchFilters(linkset)) + { + mFilteredLinksets.insert(std::pair(uuid, linkset)); } - return mFilteredLinksets; } -#else - return mAllLinksets; -#endif + + mIsFiltersDirty = false; +} + +BOOL PathfindingLinksets::doesMatchFilters(const PathfindingLinkset& pLinkset) const +{ + return ((!mIsFixedFilter || pLinkset.isFixed()) && + (!mIsWalkableFilter || pLinkset.isWalkable()) && + (!mNameFilter.isActive() || mNameFilter.doesMatch(pLinkset.getName())) && + (!mDescriptionFilter.isActive() || mDescriptionFilter.doesMatch(pLinkset.getDescription()))); } //--------------------------------------------------------------------------- @@ -352,6 +509,8 @@ const PathfindingLinksets::PathfindingLinksetMap& PathfindingLinksets::getFilter BOOL LLFloaterPathfindingLinksets::postBuild() { + childSetAction("apply_filters", boost::bind(&LLFloaterPathfindingLinksets::onApplyFiltersClicked, this)); + childSetAction("clear_filters", boost::bind(&LLFloaterPathfindingLinksets::onClearFiltersClicked, this)); childSetAction("refresh_linksets_list", boost::bind(&LLFloaterPathfindingLinksets::onRefreshLinksetsClicked, this)); childSetAction("select_all_linksets", boost::bind(&LLFloaterPathfindingLinksets::onSelectAllLinksetsClicked, this)); childSetAction("select_none_linksets", boost::bind(&LLFloaterPathfindingLinksets::onSelectNoneLinksetsClicked, this)); @@ -364,6 +523,26 @@ BOOL LLFloaterPathfindingLinksets::postBuild() mLinksetsStatus = findChild("linksets_status"); llassert(mLinksetsStatus != NULL); + mFilterByName = findChild("filter_by_name"); + llassert(mFilterByName != NULL); + mFilterByName->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyFiltersClicked, this)); + mFilterByName->setSelectAllonFocusReceived(true); + mFilterByName->setCommitOnFocusLost(true); + + mFilterByDescription = findChild("filter_by_description"); + llassert(mFilterByDescription != NULL); + mFilterByDescription->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyFiltersClicked, this)); + mFilterByDescription->setSelectAllonFocusReceived(true); + mFilterByDescription->setCommitOnFocusLost(true); + + mFilterByFixed = findChild("filter_by_fixed"); + llassert(mFilterByFixed != NULL); + mFilterByFixed->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyFiltersClicked, this)); + + mFilterByWalkable = findChild("filter_by_walkable"); + llassert(mFilterByWalkable != NULL); + mFilterByWalkable->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyFiltersClicked, this)); + setFetchState(kFetchInitial); return LLFloater::postBuild(); @@ -408,7 +587,11 @@ LLFloaterPathfindingLinksets::LLFloaterPathfindingLinksets(const LLSD& pSeed) mPathfindingLinksets(), mFetchState(kFetchInitial), mLinksetsScrollList(NULL), - mLinksetsStatus(NULL) + mLinksetsStatus(NULL), + mFilterByName(NULL), + mFilterByDescription(NULL), + mFilterByFixed(NULL), + mFilterByWalkable(NULL) { } @@ -428,7 +611,8 @@ void LLFloaterPathfindingLinksets::sendNavmeshDataGetRequest() else { setFetchState(kFetchStarting); - clearLinksetsList(); + mPathfindingLinksets.clearLinksets(); + updateLinksetsList(); LLViewerRegion* region = gAgent.getRegion(); if (region != NULL) @@ -451,9 +635,78 @@ void LLFloaterPathfindingLinksets::sendNavmeshDataGetRequest() void LLFloaterPathfindingLinksets::handleNavmeshDataGetReply(const LLSD& pNavmeshData) { setFetchState(kFetchReceived); - clearLinksetsList(); - mPathfindingLinksets.parseNavmeshData(pNavmeshData); + updateLinksetsList(); + setFetchState(kFetchComplete); +} + +void LLFloaterPathfindingLinksets::handleNavmeshDataGetError(const std::string& pURL, const std::string& pErrorReason) +{ + setFetchState(kFetchError); + mPathfindingLinksets.clearLinksets(); + updateLinksetsList(); + llwarns << "Error fetching navmesh data from URL '" << pURL << "' because " << pErrorReason << llendl; +} + +void LLFloaterPathfindingLinksets::setFetchState(EFetchState pFetchState) +{ + mFetchState = pFetchState; + updateLinksetsStatusMessage(); +} + +void LLFloaterPathfindingLinksets::onApplyFiltersClicked() +{ + applyFilters(); +} + +void LLFloaterPathfindingLinksets::onClearFiltersClicked() +{ + clearFilters(); +} + +void LLFloaterPathfindingLinksets::onLinksetsSelectionChange() +{ + updateLinksetsStatusMessage(); +} + +void LLFloaterPathfindingLinksets::onRefreshLinksetsClicked() +{ + sendNavmeshDataGetRequest(); +} + +void LLFloaterPathfindingLinksets::onSelectAllLinksetsClicked() +{ + selectAllLinksets(); +} + +void LLFloaterPathfindingLinksets::onSelectNoneLinksetsClicked() +{ + selectNoneLinksets(); +} + +void LLFloaterPathfindingLinksets::applyFilters() +{ + mPathfindingLinksets.setNameFilter(mFilterByName->getText()); + mPathfindingLinksets.setDescriptionFilter(mFilterByDescription->getText()); + mPathfindingLinksets.setFixedFilter(mFilterByFixed->get()); + mPathfindingLinksets.setWalkableFilter(mFilterByWalkable->get()); + updateLinksetsList(); +} + +void LLFloaterPathfindingLinksets::clearFilters() +{ + mPathfindingLinksets.clearFilters(); + mFilterByName->setText(LLStringExplicit(mPathfindingLinksets.getNameFilter())); + mFilterByDescription->setText(LLStringExplicit(mPathfindingLinksets.getDescriptionFilter())); + mFilterByFixed->set(mPathfindingLinksets.isFixedFilter()); + mFilterByWalkable->set(mPathfindingLinksets.isWalkableFilter()); + updateLinksetsList(); +} + +void LLFloaterPathfindingLinksets::updateLinksetsList() +{ + mLinksetsScrollList->deleteAllItems(); + updateLinksetsStatusMessage(); const LLVector3& avatarPosition = gAgent.getPositionAgent(); const PathfindingLinksets::PathfindingLinksetMap& linksetMap = mPathfindingLinksets.getFilteredLinksets(); @@ -516,46 +769,6 @@ void LLFloaterPathfindingLinksets::handleNavmeshDataGetReply(const LLSD& pNavmes mLinksetsScrollList->addElement(element); } - setFetchState(kFetchComplete); -} - -void LLFloaterPathfindingLinksets::handleNavmeshDataGetError(const std::string& pURL, const std::string& pErrorReason) -{ - setFetchState(kFetchError); - clearLinksetsList(); - llwarns << "Error fetching navmesh data from URL '" << pURL << "' because " << pErrorReason << llendl; -} - -void LLFloaterPathfindingLinksets::setFetchState(EFetchState pFetchState) -{ - mFetchState = pFetchState; - updateLinksetsStatusMessage(); -} - -void LLFloaterPathfindingLinksets::onLinksetsSelectionChange() -{ - updateLinksetsStatusMessage(); -} - -void LLFloaterPathfindingLinksets::onRefreshLinksetsClicked() -{ - sendNavmeshDataGetRequest(); -} - -void LLFloaterPathfindingLinksets::onSelectAllLinksetsClicked() -{ - selectAllLinksets(); -} - -void LLFloaterPathfindingLinksets::onSelectNoneLinksetsClicked() -{ - selectNoneLinksets(); -} - -void LLFloaterPathfindingLinksets::clearLinksetsList() -{ - mPathfindingLinksets.clearLinksets(); - mLinksetsScrollList->deleteAllItems(); updateLinksetsStatusMessage(); } @@ -626,6 +839,10 @@ void LLFloaterPathfindingLinksets::updateLinksetsStatusMessage() mLinksetsStatus->setText((LLStringExplicit)statusText, styleParams); } +//--------------------------------------------------------------------------- +// NavmeshDataGetResponder +//--------------------------------------------------------------------------- + NavmeshDataGetResponder::NavmeshDataGetResponder(const std::string& pNavmeshDataGetURL, LLFloaterPathfindingLinksets *pLinksetsFloater) : mNavmeshDataGetURL(pNavmeshDataGetURL), mLinksetsFloater(pLinksetsFloater) @@ -646,3 +863,4 @@ void NavmeshDataGetResponder::error(U32 status, const std::string& reason) { mLinksetsFloater->handleNavmeshDataGetError(mNavmeshDataGetURL, reason); } + diff --git a/indra/newview/llfloaterpathfindinglinksets.h b/indra/newview/llfloaterpathfindinglinksets.h index 93bc3834a4..0129d1f055 100644 --- a/indra/newview/llfloaterpathfindinglinksets.h +++ b/indra/newview/llfloaterpathfindinglinksets.h @@ -35,6 +35,8 @@ class LLTextBase; class LLScrollListCtrl; +class LLLineEditor; +class LLCheckBoxCtrl; class PathfindingLinkset { @@ -89,6 +91,28 @@ private: F32 mD; }; +class FilterString +{ +public: + FilterString(); + FilterString(const std::string& pFilter); + FilterString(const FilterString& pOther); + virtual ~FilterString(); + + const std::string& get() const; + bool set(const std::string& pFilter); + void clear(); + + bool isActive() const; + bool doesMatch(const std::string& pTestString) const; + +protected: + +private: + std::string mFilter; + std::string mUpperFilter; +}; + class PathfindingLinksets { public: @@ -105,9 +129,16 @@ public: const PathfindingLinksetMap& getAllLinksets() const; const PathfindingLinksetMap& getFilteredLinksets(); - BOOL isFilterActive() const; - void setNameFilter(const std::string& pNameFilter); - void clearFilters(); + BOOL isFiltersActive() const; + void setNameFilter(const std::string& pNameFilter); + const std::string& getNameFilter() const; + void setDescriptionFilter(const std::string& pDescriptionFilter); + const std::string& getDescriptionFilter() const; + void setFixedFilter(BOOL pFixedFilter); + BOOL isFixedFilter() const; + void setWalkableFilter(BOOL pWalkableFilter); + BOOL isWalkableFilter() const; + void clearFilters(); protected: @@ -115,10 +146,14 @@ private: PathfindingLinksetMap mAllLinksets; PathfindingLinksetMap mFilteredLinksets; - bool mIsFilterDirty; - std::string mNameFilter; + bool mIsFiltersDirty; + FilterString mNameFilter; + FilterString mDescriptionFilter; + BOOL mIsFixedFilter; + BOOL mIsWalkableFilter; void applyFilters(); + BOOL doesMatchFilters(const PathfindingLinkset& pLinkset) const; }; class LLFloaterPathfindingLinksets @@ -154,6 +189,10 @@ private: EFetchState mFetchState; LLScrollListCtrl *mLinksetsScrollList; LLTextBase *mLinksetsStatus; + LLLineEditor *mFilterByName; + LLLineEditor *mFilterByDescription; + LLCheckBoxCtrl *mFilterByFixed; + LLCheckBoxCtrl *mFilterByWalkable; // Does its own instance management, so clients not allowed // to allocate or destroy. @@ -163,15 +202,19 @@ private: void sendNavmeshDataGetRequest(); void handleNavmeshDataGetReply(const LLSD& pNavmeshData); void handleNavmeshDataGetError(const std::string& pURL, const std::string& pErrorReason); - void setFetchState(EFetchState pFetchState); + void onApplyFiltersClicked(); + void onClearFiltersClicked(); void onLinksetsSelectionChange(); void onRefreshLinksetsClicked(); void onSelectAllLinksetsClicked(); void onSelectNoneLinksetsClicked(); - void clearLinksetsList(); + void applyFilters(); + void clearFilters(); + + void updateLinksetsList(); void selectAllLinksets(); void selectNoneLinksets(); diff --git a/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml index 2ae2795cb5..f4631c865a 100644 --- a/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml +++ b/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml @@ -62,7 +62,7 @@ left_delta="93" top="11" max_length_bytes="10" - name="estate" + name="filter_by_name" width="115" />