555 lines
17 KiB
C++
555 lines
17 KiB
C++
/**
|
|
* @file llfloaterpathfindingcharacters.cpp
|
|
* @author William Todd Stinson
|
|
* @brief "Pathfinding characters" floater, allowing for identification of pathfinding characters and their cpu usage.
|
|
*
|
|
* $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 "llpathfindingcharacterlist.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"
|
|
#include "llviewerobject.h"
|
|
#include "llviewerobjectlist.h"
|
|
#include "llviewermenu.h"
|
|
#include "llselectmgr.h"
|
|
#include "llenvmanager.h"
|
|
|
|
//---------------------------------------------------------------------------
|
|
// LLFloaterPathfindingCharacters
|
|
//---------------------------------------------------------------------------
|
|
|
|
BOOL LLFloaterPathfindingCharacters::postBuild()
|
|
{
|
|
mCharactersScrollList = findChild<LLScrollListCtrl>("pathfinding_characters");
|
|
llassert(mCharactersScrollList != NULL);
|
|
mCharactersScrollList->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onCharactersSelectionChange, this));
|
|
mCharactersScrollList->sortByColumnIndex(0, true);
|
|
|
|
mCharactersStatus = findChild<LLTextBase>("characters_status");
|
|
llassert(mCharactersStatus != NULL);
|
|
|
|
mRefreshListButton = findChild<LLButton>("refresh_characters_list");
|
|
llassert(mRefreshListButton != NULL);
|
|
mRefreshListButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onRefreshCharactersClicked, this));
|
|
|
|
mSelectAllButton = findChild<LLButton>("select_all_characters");
|
|
llassert(mSelectAllButton != NULL);
|
|
mSelectAllButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onSelectAllCharactersClicked, this));
|
|
|
|
mSelectNoneButton = findChild<LLButton>("select_none_characters");
|
|
llassert(mSelectNoneButton != NULL);
|
|
mSelectNoneButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onSelectNoneCharactersClicked, this));
|
|
|
|
mShowBeaconCheckBox = findChild<LLCheckBoxCtrl>("show_beacon");
|
|
llassert(mShowBeaconCheckBox != NULL);
|
|
|
|
mTakeButton = findChild<LLButton>("take_characters");
|
|
llassert(mTakeButton != NULL)
|
|
mTakeButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onTakeCharactersClicked, this));
|
|
|
|
mTakeCopyButton = findChild<LLButton>("take_copy_characters");
|
|
llassert(mTakeCopyButton != NULL)
|
|
mTakeCopyButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onTakeCopyCharactersClicked, this));
|
|
|
|
mReturnButton = findChild<LLButton>("return_characters");
|
|
llassert(mReturnButton != NULL)
|
|
mReturnButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onReturnCharactersClicked, this));
|
|
|
|
mDeleteButton = findChild<LLButton>("delete_characters");
|
|
llassert(mDeleteButton != NULL)
|
|
mDeleteButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onDeleteCharactersClicked, this));
|
|
|
|
mTeleportButton = findChild<LLButton>("teleport_to_character");
|
|
llassert(mTeleportButton != NULL)
|
|
mTeleportButton->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onTeleportCharacterToMeClicked, this));
|
|
|
|
return LLFloater::postBuild();
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::onOpen(const LLSD& pKey)
|
|
{
|
|
LLFloater::onOpen(pKey);
|
|
|
|
requestGetCharacters();
|
|
selectNoneCharacters();
|
|
mCharactersScrollList->setCommitOnSelectionChange(true);
|
|
|
|
if (!mSelectionUpdateSlot.connected())
|
|
{
|
|
mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterPathfindingCharacters::updateControls, this));
|
|
}
|
|
|
|
if (!mRegionBoundarySlot.connected())
|
|
{
|
|
mRegionBoundarySlot = LLEnvManagerNew::instance().setRegionChangeCallback(boost::bind(&LLFloaterPathfindingCharacters::onRegionBoundaryCross, this));
|
|
}
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::onClose(bool pAppQuitting)
|
|
{
|
|
if (mRegionBoundarySlot.connected())
|
|
{
|
|
mRegionBoundarySlot.disconnect();
|
|
}
|
|
|
|
if (mSelectionUpdateSlot.connected())
|
|
{
|
|
mSelectionUpdateSlot.disconnect();
|
|
}
|
|
|
|
mCharactersScrollList->setCommitOnSelectionChange(false);
|
|
selectNoneCharacters();
|
|
if (mCharacterSelection.notNull())
|
|
{
|
|
mCharacterSelection.clear();
|
|
}
|
|
|
|
LLFloater::onClose(pAppQuitting);
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::draw()
|
|
{
|
|
if (mShowBeaconCheckBox->get())
|
|
{
|
|
std::vector<LLScrollListItem*> selectedItems = mCharactersScrollList->getAllSelected();
|
|
if (!selectedItems.empty())
|
|
{
|
|
int numSelectedItems = selectedItems.size();
|
|
|
|
std::vector<LLViewerObject *> viewerObjects;
|
|
viewerObjects.reserve(numSelectedItems);
|
|
|
|
for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin();
|
|
selectedItemIter != selectedItems.end(); ++selectedItemIter)
|
|
{
|
|
const LLScrollListItem *selectedItem = *selectedItemIter;
|
|
|
|
const std::string &objectName = selectedItem->getColumn(0)->getValue().asString();
|
|
|
|
LLViewerObject *viewerObject = gObjectList.findObject(selectedItem->getUUID());
|
|
if (viewerObject != NULL)
|
|
{
|
|
gObjectList.addDebugBeacon(viewerObject->getPositionAgent(), objectName, LLColor4(0.f, 0.f, 1.f, 0.8f), LLColor4(1.f, 1.f, 1.f, 1.f), 6);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LLFloater::draw();
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::openCharactersViewer()
|
|
{
|
|
LLFloaterReg::toggleInstanceOrBringToFront("pathfinding_characters");
|
|
}
|
|
|
|
LLFloaterPathfindingCharacters::LLFloaterPathfindingCharacters(const LLSD& pSeed)
|
|
: LLFloater(pSeed),
|
|
mCharactersScrollList(NULL),
|
|
mCharactersStatus(NULL),
|
|
mRefreshListButton(NULL),
|
|
mSelectAllButton(NULL),
|
|
mSelectNoneButton(NULL),
|
|
mShowBeaconCheckBox(NULL),
|
|
mTakeButton(NULL),
|
|
mTakeCopyButton(NULL),
|
|
mReturnButton(NULL),
|
|
mDeleteButton(NULL),
|
|
mTeleportButton(NULL),
|
|
mMessagingState(kMessagingUnknown),
|
|
mMessagingRequestId(0U),
|
|
mCharacterListPtr(),
|
|
mCharacterSelection(),
|
|
mSelectionUpdateSlot()
|
|
{
|
|
}
|
|
|
|
LLFloaterPathfindingCharacters::~LLFloaterPathfindingCharacters()
|
|
{
|
|
}
|
|
|
|
LLFloaterPathfindingCharacters::EMessagingState LLFloaterPathfindingCharacters::getMessagingState() const
|
|
{
|
|
return mMessagingState;
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::setMessagingState(EMessagingState pMessagingState)
|
|
{
|
|
mMessagingState = pMessagingState;
|
|
updateControls();
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::requestGetCharacters()
|
|
{
|
|
switch (LLPathfindingManager::getInstance()->requestGetCharacters(++mMessagingRequestId, boost::bind(&LLFloaterPathfindingCharacters::handleNewCharacters, this, _1, _2, _3)))
|
|
{
|
|
case LLPathfindingManager::kRequestStarted :
|
|
setMessagingState(kMessagingGetRequestSent);
|
|
break;
|
|
case LLPathfindingManager::kRequestCompleted :
|
|
clearCharacters();
|
|
setMessagingState(kMessagingComplete);
|
|
break;
|
|
case LLPathfindingManager::kRequestNotEnabled :
|
|
clearCharacters();
|
|
setMessagingState(kMessagingNotEnabled);
|
|
break;
|
|
case LLPathfindingManager::kRequestError :
|
|
setMessagingState(kMessagingGetError);
|
|
break;
|
|
default :
|
|
setMessagingState(kMessagingGetError);
|
|
llassert(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::handleNewCharacters(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pCharacterRequestStatus, LLPathfindingCharacterListPtr pCharacterListPtr)
|
|
{
|
|
llassert(pRequestId <= mMessagingRequestId);
|
|
if (pRequestId == mMessagingRequestId)
|
|
{
|
|
mCharacterListPtr = pCharacterListPtr;
|
|
updateScrollList();
|
|
|
|
switch (pCharacterRequestStatus)
|
|
{
|
|
case LLPathfindingManager::kRequestCompleted :
|
|
setMessagingState(kMessagingComplete);
|
|
break;
|
|
case LLPathfindingManager::kRequestError :
|
|
setMessagingState(kMessagingGetError);
|
|
break;
|
|
default :
|
|
setMessagingState(kMessagingGetError);
|
|
llassert(0);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::onCharactersSelectionChange()
|
|
{
|
|
mCharacterSelection.clear();
|
|
LLSelectMgr::getInstance()->deselectAll();
|
|
|
|
std::vector<LLScrollListItem*> selectedItems = mCharactersScrollList->getAllSelected();
|
|
if (!selectedItems.empty())
|
|
{
|
|
int numSelectedItems = selectedItems.size();
|
|
|
|
std::vector<LLViewerObject *> viewerObjects;
|
|
viewerObjects.reserve(numSelectedItems);
|
|
|
|
for (std::vector<LLScrollListItem*>::const_iterator selectedItemIter = selectedItems.begin();
|
|
selectedItemIter != selectedItems.end(); ++selectedItemIter)
|
|
{
|
|
const LLScrollListItem *selectedItem = *selectedItemIter;
|
|
|
|
LLViewerObject *viewerObject = gObjectList.findObject(selectedItem->getUUID());
|
|
if (viewerObject != NULL)
|
|
{
|
|
viewerObjects.push_back(viewerObject);
|
|
}
|
|
}
|
|
|
|
if (!viewerObjects.empty())
|
|
{
|
|
mCharacterSelection = LLSelectMgr::getInstance()->selectObjectAndFamily(viewerObjects);
|
|
}
|
|
}
|
|
|
|
updateControls();
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::onRefreshCharactersClicked()
|
|
{
|
|
requestGetCharacters();
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::onSelectAllCharactersClicked()
|
|
{
|
|
selectAllCharacters();
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::onSelectNoneCharactersClicked()
|
|
{
|
|
selectNoneCharacters();
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::onTakeCharactersClicked()
|
|
{
|
|
handle_take();
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::onTakeCopyCharactersClicked()
|
|
{
|
|
handle_take_copy();
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::onReturnCharactersClicked()
|
|
{
|
|
handle_object_return();
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::onDeleteCharactersClicked()
|
|
{
|
|
handle_object_delete();
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::onTeleportCharacterToMeClicked()
|
|
{
|
|
std::vector<LLScrollListItem*> selectedItems = mCharactersScrollList->getAllSelected();
|
|
llassert(selectedItems.size() == 1);
|
|
if (selectedItems.size() == 1)
|
|
{
|
|
std::vector<LLScrollListItem*>::const_reference selectedItemRef = selectedItems.front();
|
|
const LLScrollListItem *selectedItem = selectedItemRef;
|
|
LLPathfindingCharacterList::const_iterator characterIter = mCharacterListPtr->find(selectedItem->getUUID().asString());
|
|
const LLPathfindingCharacterPtr &characterPtr = characterIter->second;
|
|
const LLVector3 &characterLocation = characterPtr->getLocation();
|
|
|
|
LLViewerRegion* region = gAgent.getRegion();
|
|
if (region != NULL)
|
|
{
|
|
gAgent.teleportRequest(region->getHandle(), characterLocation, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::onRegionBoundaryCross()
|
|
{
|
|
requestGetCharacters();
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::selectAllCharacters()
|
|
{
|
|
mCharactersScrollList->selectAll();
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::selectNoneCharacters()
|
|
{
|
|
mCharactersScrollList->deselectAllItems();
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::clearCharacters()
|
|
{
|
|
if (mCharacterListPtr != NULL)
|
|
{
|
|
mCharacterListPtr->clear();
|
|
}
|
|
updateScrollList();
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::updateControls()
|
|
{
|
|
updateStatusMessage();
|
|
updateEnableStateOnListActions();
|
|
updateEnableStateOnEditFields();
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::updateScrollList()
|
|
{
|
|
std::vector<LLScrollListItem*> selectedItems = mCharactersScrollList->getAllSelected();
|
|
int numSelectedItems = selectedItems.size();
|
|
uuid_vec_t selectedUUIDs;
|
|
if (numSelectedItems > 0)
|
|
{
|
|
selectedUUIDs.reserve(selectedItems.size());
|
|
for (std::vector<LLScrollListItem*>::const_iterator itemIter = selectedItems.begin();
|
|
itemIter != selectedItems.end(); ++itemIter)
|
|
{
|
|
const LLScrollListItem *listItem = *itemIter;
|
|
selectedUUIDs.push_back(listItem->getUUID());
|
|
}
|
|
}
|
|
|
|
S32 origScrollPosition = mCharactersScrollList->getScrollPos();
|
|
mCharactersScrollList->deleteAllItems();
|
|
|
|
if (mCharacterListPtr != NULL)
|
|
{
|
|
for (LLPathfindingCharacterList::const_iterator characterIter = mCharacterListPtr->begin();
|
|
characterIter != mCharacterListPtr->end(); ++characterIter)
|
|
{
|
|
const LLPathfindingCharacterPtr& character(characterIter->second);
|
|
LLSD element = buildCharacterScrollListElement(character);
|
|
mCharactersScrollList->addElement(element);
|
|
}
|
|
}
|
|
|
|
mCharactersScrollList->selectMultiple(selectedUUIDs);
|
|
mCharactersScrollList->setScrollPos(origScrollPosition);
|
|
updateControls();
|
|
}
|
|
|
|
LLSD LLFloaterPathfindingCharacters::buildCharacterScrollListElement(const LLPathfindingCharacterPtr pCharacterPtr) const
|
|
{
|
|
LLSD columns;
|
|
|
|
columns[0]["column"] = "name";
|
|
columns[0]["value"] = pCharacterPtr->getName();
|
|
columns[0]["font"] = "SANSSERIF";
|
|
|
|
columns[1]["column"] = "description";
|
|
columns[1]["value"] = pCharacterPtr->getDescription();
|
|
columns[1]["font"] = "SANSSERIF";
|
|
|
|
columns[2]["column"] = "owner";
|
|
columns[2]["value"] = pCharacterPtr->getOwnerName();
|
|
columns[2]["font"] = "SANSSERIF";
|
|
|
|
S32 cpuTime = llround(pCharacterPtr->getCPUTime());
|
|
std::string cpuTimeString = llformat("%d", cpuTime);
|
|
LLStringUtil::format_map_t string_args;
|
|
string_args["[CPU_TIME]"] = cpuTimeString;
|
|
|
|
columns[3]["column"] = "cpu_time";
|
|
columns[3]["value"] = getString("character_cpu_time", string_args);
|
|
columns[3]["font"] = "SANSSERIF";
|
|
|
|
columns[4]["column"] = "altitude";
|
|
columns[4]["value"] = llformat("%1.0f m", pCharacterPtr->getLocation()[2]);
|
|
columns[4]["font"] = "SANSSERIF";
|
|
|
|
LLSD element;
|
|
element["id"] = pCharacterPtr->getUUID().asString();
|
|
element["column"] = columns;
|
|
|
|
return element;
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::updateStatusMessage()
|
|
{
|
|
static const LLColor4 warningColor = LLUIColorTable::instance().getColor("DrYellow");
|
|
|
|
std::string statusText("");
|
|
LLStyle::Params styleParams;
|
|
|
|
switch (getMessagingState())
|
|
{
|
|
case kMessagingUnknown:
|
|
statusText = getString("characters_messaging_initial");
|
|
break;
|
|
case kMessagingGetRequestSent :
|
|
statusText = getString("characters_messaging_get_inprogress");
|
|
break;
|
|
case kMessagingGetError :
|
|
statusText = getString("characters_messaging_get_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;
|
|
case kMessagingNotEnabled:
|
|
statusText = getString("characters_messaging_not_enabled");
|
|
styleParams.color = warningColor;
|
|
break;
|
|
default:
|
|
statusText = getString("characters_messaging_initial");
|
|
llassert(0);
|
|
break;
|
|
}
|
|
|
|
mCharactersStatus->setText((LLStringExplicit)statusText, styleParams);
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::updateEnableStateOnListActions()
|
|
{
|
|
switch (getMessagingState())
|
|
{
|
|
case kMessagingUnknown:
|
|
case kMessagingGetRequestSent :
|
|
mRefreshListButton->setEnabled(FALSE);
|
|
mSelectAllButton->setEnabled(FALSE);
|
|
mSelectNoneButton->setEnabled(FALSE);
|
|
break;
|
|
case kMessagingGetError :
|
|
case kMessagingNotEnabled :
|
|
mRefreshListButton->setEnabled(TRUE);
|
|
mSelectAllButton->setEnabled(FALSE);
|
|
mSelectNoneButton->setEnabled(FALSE);
|
|
break;
|
|
case kMessagingComplete :
|
|
{
|
|
int numItems = mCharactersScrollList->getItemCount();
|
|
int numSelectedItems = mCharactersScrollList->getNumSelected();
|
|
mRefreshListButton->setEnabled(TRUE);
|
|
mSelectAllButton->setEnabled(numSelectedItems < numItems);
|
|
mSelectNoneButton->setEnabled(numSelectedItems > 0);
|
|
}
|
|
break;
|
|
default:
|
|
llassert(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void LLFloaterPathfindingCharacters::updateEnableStateOnEditFields()
|
|
{
|
|
int numSelectedItems = mCharactersScrollList->getNumSelected();
|
|
bool isEditEnabled = (numSelectedItems > 0);
|
|
|
|
mShowBeaconCheckBox->setEnabled(isEditEnabled);
|
|
mTakeButton->setEnabled(isEditEnabled && visible_take_object());
|
|
mTakeCopyButton->setEnabled(isEditEnabled && enable_object_take_copy());
|
|
mReturnButton->setEnabled(isEditEnabled && enable_object_return());
|
|
mDeleteButton->setEnabled(isEditEnabled && enable_object_delete());
|
|
mTeleportButton->setEnabled(numSelectedItems == 1);
|
|
}
|