From 525343b9e5f39dafafe2a16e8173ad7f69acb0d6 Mon Sep 17 00:00:00 2001 From: Todd Stinson Date: Thu, 2 Feb 2012 18:30:35 -0800 Subject: PATH-245: First pass at laying out the characters floater. Functionality is mostly stubbed in. The data is currently tied to the same cap service as the linkset data, so that will need to change as soon as the new service is available. --- indra/newview/llfloaterpathfindingcharacters.cpp | 491 +++++++++++++++++++++++ 1 file changed, 491 insertions(+) create mode 100644 indra/newview/llfloaterpathfindingcharacters.cpp (limited to 'indra/newview/llfloaterpathfindingcharacters.cpp') diff --git a/indra/newview/llfloaterpathfindingcharacters.cpp b/indra/newview/llfloaterpathfindingcharacters.cpp new file mode 100644 index 0000000000..021b48f0a0 --- /dev/null +++ b/indra/newview/llfloaterpathfindingcharacters.cpp @@ -0,0 +1,491 @@ +/** + * @file llfloaterpathfindingcharacters.cpp + * @author William Todd Stinson + * @brief "Pathfinding linksets" floater, allowing manipulation of the Havok AI pathfinding settings. + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, 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 "llfloater.h" +#include "llfloaterpathfindingcharacters.h" +#include "llpathfindingcharacter.h" +#include "llsd.h" +#include "llagent.h" +#include "llhandle.h" +#include "llfloaterreg.h" +#include "lltextbase.h" +#include "llscrolllistitem.h" +#include "llscrolllistctrl.h" +#include "llcheckboxctrl.h" +#include "llradiogroup.h" +#include "llbutton.h" +#include "llresmgr.h" +#include "llviewerregion.h" +#include "llhttpclient.h" +#include "lluuid.h" + +//--------------------------------------------------------------------------- +// CharactersGetResponder +//--------------------------------------------------------------------------- + +class CharactersGetResponder : public LLHTTPClient::Responder +{ +public: + CharactersGetResponder(const std::string& pCharactersDataGetURL, + const LLHandle &pCharactersFloaterHandle); + virtual ~CharactersGetResponder(); + + virtual void result(const LLSD& pContent); + virtual void error(U32 pStatus, const std::string& pReason); + +private: + CharactersGetResponder(const CharactersGetResponder& pOther); + + std::string mCharactersDataGetURL; + LLHandle mCharactersFloaterHandle; +}; + +//--------------------------------------------------------------------------- +// LLFloaterPathfindingCharacters +//--------------------------------------------------------------------------- + +BOOL LLFloaterPathfindingCharacters::postBuild() +{ + childSetAction("refresh_characters_list", boost::bind(&LLFloaterPathfindingCharacters::onRefreshCharactersClicked, this)); + childSetAction("select_all_characters", boost::bind(&LLFloaterPathfindingCharacters::onSelectAllCharactersClicked, this)); + childSetAction("select_none_characters", boost::bind(&LLFloaterPathfindingCharacters::onSelectNoneCharactersClicked, this)); + + mCharactersScrollList = findChild("pathfinding_characters"); + llassert(mCharactersScrollList != NULL); + mCharactersScrollList->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onCharactersSelectionChange, this)); + mCharactersScrollList->setCommitOnSelectionChange(true); + mCharactersScrollList->sortByColumnIndex(0, true); + + mCharactersStatus = findChild("characters_status"); + llassert(mCharactersStatus != NULL); + + mLabelActions = findChild("actions_label"); + llassert(mLabelActions != NULL); + + mShowBeaconCheckBox = findChild("show_beacon"); + llassert(mShowBeaconCheckBox != NULL); + mShowBeaconCheckBox->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onShowBeaconToggled, this)); + + mTakeBtn = findChild("take_characters"); + llassert(mTakeBtn != NULL) + mTakeBtn->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onTakeCharactersClicked, this)); + + mTakeCopyBtn = findChild("take_copy_characters"); + llassert(mTakeCopyBtn != NULL) + mTakeCopyBtn->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onTakeCopyCharactersClicked, this)); + + mReturnBtn = findChild("return_characters"); + llassert(mReturnBtn != NULL) + mReturnBtn->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onReturnCharactersClicked, this)); + + mDeleteBtn = findChild("delete_characters"); + llassert(mDeleteBtn != NULL) + mDeleteBtn->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onDeleteCharactersClicked, this)); + + mTeleportBtn = findChild("teleport_to_character"); + llassert(mTeleportBtn != NULL) + mTeleportBtn->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onTeleportCharacterToMeClicked, this)); + + setEnableActionFields(false); + setMessagingState(kMessagingInitial); + + return LLFloater::postBuild(); +} + +void LLFloaterPathfindingCharacters::onOpen(const LLSD& pKey) +{ + sendCharactersDataGetRequest(); +} + +LLFloaterPathfindingCharacters::EMessagingState LLFloaterPathfindingCharacters::getMessagingState() const +{ + return mMessagingState; +} + +BOOL LLFloaterPathfindingCharacters::isMessagingInProgress() const +{ + BOOL retVal; + switch (getMessagingState()) + { + case kMessagingFetchStarting : + case kMessagingFetchRequestSent : + case kMessagingFetchRequestSent_MultiRequested : + case kMessagingFetchReceived : + retVal = true; + break; + default : + retVal = false; + break; + } + + return retVal; +} + +LLFloaterPathfindingCharacters::LLFloaterPathfindingCharacters(const LLSD& pSeed) + : LLFloater(pSeed), + mSelfHandle(), + mPathfindingCharacters(), + mMessagingState(kMessagingInitial), + mCharactersScrollList(NULL), + mCharactersStatus(NULL), + mLabelActions(NULL), + mShowBeaconCheckBox(NULL), + mTakeBtn(NULL), + mTakeCopyBtn(NULL), + mReturnBtn(NULL), + mDeleteBtn(NULL), + mTeleportBtn(NULL) +{ + mSelfHandle.bind(this); +} + +LLFloaterPathfindingCharacters::~LLFloaterPathfindingCharacters() +{ + mPathfindingCharacters.clear(); +} + +void LLFloaterPathfindingCharacters::sendCharactersDataGetRequest() +{ + if (isMessagingInProgress()) + { + if (getMessagingState() == kMessagingFetchRequestSent) + { + setMessagingState(kMessagingFetchRequestSent_MultiRequested); + } + } + else + { + setMessagingState(kMessagingFetchStarting); + mPathfindingCharacters.clear(); + updateCharactersList(); + + std::string charactersDataURL = getCapabilityURL(); + if (charactersDataURL.empty()) + { + setMessagingState(kMessagingComplete); + llwarns << "cannot query pathfinding characters from current region '" << getRegionName() << "'" << llendl; + } + else + { + setMessagingState(kMessagingFetchRequestSent); + LLHTTPClient::get(charactersDataURL, new CharactersGetResponder(charactersDataURL, mSelfHandle)); + } + } +} + +void LLFloaterPathfindingCharacters::handleCharactersDataGetReply(const LLSD& pCharactersData) +{ + setMessagingState(kMessagingFetchReceived); + mPathfindingCharacters.clear(); + parseCharactersData(pCharactersData); + updateCharactersList(); + setMessagingState(kMessagingComplete); +} + +void LLFloaterPathfindingCharacters::handleCharactersDataGetError(const std::string& pURL, const std::string& pErrorReason) +{ + setMessagingState(kMessagingFetchError); + mPathfindingCharacters.clear(); + updateCharactersList(); + llwarns << "Error fetching pathfinding characters from URL '" << pURL << "' because " << pErrorReason << llendl; +} + +std::string LLFloaterPathfindingCharacters::getRegionName() const +{ + std::string regionName(""); + + LLViewerRegion* region = gAgent.getRegion(); + if (region != NULL) + { + regionName = region->getName(); + } + + return regionName; +} + +std::string LLFloaterPathfindingCharacters::getCapabilityURL() const +{ + std::string charactersDataURL(""); + + LLViewerRegion* region = gAgent.getRegion(); + if (region != NULL) + { + charactersDataURL = region->getCapability("ObjectNavMeshProperties"); + } + + return charactersDataURL; +} + +void LLFloaterPathfindingCharacters::parseCharactersData(const LLSD &pCharactersData) +{ + for (LLSD::map_const_iterator characterItemIter = pCharactersData.beginMap(); + characterItemIter != pCharactersData.endMap(); ++characterItemIter) + { + const std::string &uuid(characterItemIter->first); + const LLSD &characterData(characterItemIter->second); + LLPathfindingCharacter character(uuid, characterData); + + mPathfindingCharacters.insert(std::pair(uuid, character)); + } +} + +void LLFloaterPathfindingCharacters::setMessagingState(EMessagingState pMessagingState) +{ + mMessagingState = pMessagingState; + updateCharactersList(); + updateActionFields(); +} + +void LLFloaterPathfindingCharacters::onCharactersSelectionChange() +{ + updateCharactersStatusMessage(); + updateActionFields(); +} + +void LLFloaterPathfindingCharacters::onRefreshCharactersClicked() +{ + sendCharactersDataGetRequest(); +} + +void LLFloaterPathfindingCharacters::onSelectAllCharactersClicked() +{ + selectAllCharacters(); +} + +void LLFloaterPathfindingCharacters::onSelectNoneCharactersClicked() +{ + selectNoneCharacters(); +} + +void LLFloaterPathfindingCharacters::onShowBeaconToggled() +{ + llwarns << "functionality has not yet been implemented to toggle show beacon" << llendl; +} + +void LLFloaterPathfindingCharacters::onTakeCharactersClicked() +{ + llwarns << "functionality has not yet been implemented to take characters" << llendl; +} + +void LLFloaterPathfindingCharacters::onTakeCopyCharactersClicked() +{ + llwarns << "functionality has not yet been implemented to take a copy of characters" << llendl; +} + +void LLFloaterPathfindingCharacters::onReturnCharactersClicked() +{ + llwarns << "functionality has not yet been implemented to return characters" << llendl; +} + +void LLFloaterPathfindingCharacters::onDeleteCharactersClicked() +{ + llwarns << "functionality has not yet been implemented to delete characters" << llendl; +} + +void LLFloaterPathfindingCharacters::onTeleportCharacterToMeClicked() +{ + llwarns << "functionality has not yet been implemented to teleport me tothe character" << llendl; +} + +void LLFloaterPathfindingCharacters::updateCharactersList() +{ + std::vector selectedItems = mCharactersScrollList->getAllSelected(); + int numSelectedItems = selectedItems.size(); + uuid_vec_t selectedUUIDs; + if (numSelectedItems > 0) + { + selectedUUIDs.reserve(selectedItems.size()); + for (std::vector::const_iterator itemIter = selectedItems.begin(); + itemIter != selectedItems.end(); ++itemIter) + { + const LLScrollListItem *listItem = *itemIter; + selectedUUIDs.push_back(listItem->getUUID()); + } + } + + mCharactersScrollList->deleteAllItems(); + updateCharactersStatusMessage(); + + for (PathfindingCharacterMap::const_iterator characterIter = mPathfindingCharacters.begin(); + characterIter != mPathfindingCharacters.end(); ++characterIter) + { + const LLPathfindingCharacter& character(characterIter->second); + + LLSD columns; + + columns[0]["column"] = "name"; + columns[0]["value"] = character.getName(); + columns[0]["font"] = "SANSSERIF"; + + columns[1]["column"] = "description"; + columns[1]["value"] = character.getDescription(); + columns[1]["font"] = "SANSSERIF"; + + columns[2]["column"] = "owner"; + columns[2]["value"] = character.getOwner(); + columns[2]["font"] = "SANSSERIF"; + + columns[3]["column"] = "cpu_time"; + columns[3]["value"] = llformat("%3d ms", character.getCPUTime()); + columns[3]["font"] = "SANSSERIF"; + + columns[4]["column"] = "altitude"; + columns[4]["value"] = llformat("%1.0f m", character.getLocation()[2]); + columns[4]["font"] = "SANSSERIF"; + + LLSD element; + element["id"] = character.getUUID().asString(); + element["column"] = columns; + + mCharactersScrollList->addElement(element); + } + + mCharactersScrollList->selectMultiple(selectedUUIDs); + updateCharactersStatusMessage(); + updateActionFields(); +} + +void LLFloaterPathfindingCharacters::selectAllCharacters() +{ + mCharactersScrollList->selectAll(); +} + +void LLFloaterPathfindingCharacters::selectNoneCharacters() +{ + mCharactersScrollList->deselectAllItems(); +} + +void LLFloaterPathfindingCharacters::updateCharactersStatusMessage() +{ + static const LLColor4 warningColor = LLUIColorTable::instance().getColor("DrYellow"); + + std::string statusText(""); + LLStyle::Params styleParams; + + switch (getMessagingState()) + { + case kMessagingInitial: + statusText = getString("characters_messaging_initial"); + break; + case kMessagingFetchStarting : + statusText = getString("characters_messaging_fetch_starting"); + break; + case kMessagingFetchRequestSent : + statusText = getString("characters_messaging_fetch_inprogress"); + break; + case kMessagingFetchRequestSent_MultiRequested : + statusText = getString("characters_messaging_fetch_inprogress_multi_request"); + break; + case kMessagingFetchReceived : + statusText = getString("characters_messaging_fetch_received"); + break; + case kMessagingFetchError : + statusText = getString("characters_messaging_fetch_error"); + styleParams.color = warningColor; + break; + case kMessagingComplete : + if (mCharactersScrollList->isEmpty()) + { + statusText = getString("characters_messaging_complete_none_found"); + } + else + { + S32 numItems = mCharactersScrollList->getItemCount(); + S32 numSelectedItems = mCharactersScrollList->getNumSelected(); + + LLLocale locale(LLStringUtil::getLocale()); + std::string numItemsString; + LLResMgr::getInstance()->getIntegerString(numItemsString, numItems); + + std::string numSelectedItemsString; + LLResMgr::getInstance()->getIntegerString(numSelectedItemsString, numSelectedItems); + + LLStringUtil::format_map_t string_args; + string_args["[NUM_SELECTED]"] = numSelectedItemsString; + string_args["[NUM_TOTAL]"] = numItemsString; + statusText = getString("characters_messaging_complete_available", string_args); + } + break; + default: + statusText = getString("characters_messaging_initial"); + llassert(0); + break; + } + + mCharactersStatus->setText((LLStringExplicit)statusText, styleParams); +} + +void LLFloaterPathfindingCharacters::updateActionFields() +{ + std::vector selectedItems = mCharactersScrollList->getAllSelected(); + setEnableActionFields(!selectedItems.empty()); +} + +void LLFloaterPathfindingCharacters::setEnableActionFields(BOOL pEnabled) +{ + mLabelActions->setEnabled(pEnabled); + mShowBeaconCheckBox->setEnabled(pEnabled); + mTakeBtn->setEnabled(pEnabled); + mTakeCopyBtn->setEnabled(pEnabled); + mReturnBtn->setEnabled(pEnabled); + mDeleteBtn->setEnabled(pEnabled); + mTeleportBtn->setEnabled(pEnabled && (mCharactersScrollList->getNumSelected() == 1)); +} + +//--------------------------------------------------------------------------- +// CharactersGetResponder +//--------------------------------------------------------------------------- + +CharactersGetResponder::CharactersGetResponder(const std::string& pCharactersDataGetURL, + const LLHandle &pCharactersFloaterHandle) + : mCharactersDataGetURL(pCharactersDataGetURL), + mCharactersFloaterHandle(pCharactersFloaterHandle) +{ +} + +CharactersGetResponder::~CharactersGetResponder() +{ +} + +void CharactersGetResponder::result(const LLSD& pContent) +{ + LLFloaterPathfindingCharacters *charactersFloater = mCharactersFloaterHandle.get(); + if (charactersFloater != NULL) + { + charactersFloater->handleCharactersDataGetReply(pContent); + } +} + +void CharactersGetResponder::error(U32 status, const std::string& reason) +{ + LLFloaterPathfindingCharacters *charactersFloater = mCharactersFloaterHandle.get(); + if (charactersFloater != NULL) + { + charactersFloater->handleCharactersDataGetError(mCharactersDataGetURL, reason); + } +} -- cgit v1.2.3